251128 Lodash 자바스크립트 유틸리티 라이브러리 완전정복
28 Nov 2025
Lodash: JavaScript 개발자를 위한 필수 유틸리티 라이브러리
서론
JavaScript 프로젝트에서 배열, 객체, 문자열을 다루다 보면 반복적이고 복잡한 코드를 작성하게 됩니다. 특히 깊은 객체 복사, 배열 조작, 함수 디바운싱 등의 작업은 매번 구현하기 번거롭고 버그가 발생하기 쉽습니다.
Lodash는 이러한 문제를 해결해주는 JavaScript 유틸리티 라이브러리로, 개발 생산성을 크게 향상시켜줍니다. 이 글에서는 Lodash의 특징, 장단점, 그리고 실무에서 활용할 수 있는 다양한 예제들을 살펴보겠습니다.
Lodash란 무엇인가?
Lodash는 JavaScript 유틸리티 라이브러리로, 배열, 객체, 문자열, 함수 등을 다루는 편리한 유틸리티 함수들을 제공합니다. JavaScript의 기본 기능을 확장하여 더 간결하고 안전한 코드를 작성할 수 있게 해줍니다.
핵심 특징
1. 함수형 프로그래밍 지원
// 체이닝을 통한 함수형 스타일
const result = _(users)
.filter({ active: true })
.orderBy(["age"], ["desc"])
.map("name")
.take(2)
.value();
2. 크로스 브라우저 호환성
- 구형 브라우저에서도 일관된 동작
- 다양한 환경에서 안정적 실행
3. 성능 최적화
- 내부적으로 최적화된 알고리즘
- 지연 평가(Lazy Evaluation) 지원
4. 모듈화
// 필요한 함수만 개별 import
import debounce from "lodash/debounce";
import cloneDeep from "lodash/cloneDeep";
장단점 분석
장점
- 생산성 향상: 복잡한 데이터 조작을 간단한 코드로 처리
- 코드 안전성: null/undefined 체크 등 안전한 함수들 제공
- 가독성: 직관적이고 일관된 API
- 테스트된 코드: 수많은 프로젝트에서 검증됨
단점
- 번들 크기: 전체 라이브러리 사용 시 크기가 큼 (67KB)
- 최신 JS 기능: ES6+ 기능으로 대체 가능한 것들 多
- 의존성: 외부 라이브러리 의존성 추가
- 오버 엔지니어링: 간단한 작업에도 라이브러리 사용하는 경향
실무 활용 예제
1. 배열 조작의 달인 되기
중복 제거와 배열 분할
import _ from "lodash";
// 배열에서 중복 제거
const numbers = [1, 2, 2, 3, 4, 4, 5];
const unique = _.uniq(numbers); // [1, 2, 3, 4, 5]
// 배열 청크 분할 - 페이지네이션에 유용
const items = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const pages = _.chunk(items, 3); // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
// 배열 평탄화
const nested = [1, [2, 3], [4, [5, 6]]];
const flatten = _.flatten(nested); // [1, 2, 3, 4, [5, 6]]
const flattenDeep = _.flattenDeep(nested); // [1, 2, 3, 4, 5, 6]
고급 배열 연산
const products = [
{ id: 1, name: "노트북", price: 1000, category: "전자제품" },
{ id: 2, name: "마우스", price: 50, category: "전자제품" },
{ id: 3, name: "책", price: 20, category: "도서" }
];
// 특정 조건으로 찾기
const laptop = _.find(products, { name: "노트북" });
// 여러 조건으로 필터링
const electronics = _.filter(products, { category: "전자제품" });
// 가격 순 정렬
const sortedByPrice = _.orderBy(products, ["price"], ["desc"]);
2. 객체 조작의 마법사
안전한 객체 조작
// 깊은 복사 - 참조 문제 해결
const original = {
user: {
profile: {
name: "홍길동",
preferences: { theme: "dark" }
}
}
};
const cloned = _.cloneDeep(original);
// 안전한 중첩 속성 접근
const user = { profile: { name: "홍길동" } };
const name = _.get(user, "profile.name", "이름 없음"); // "홍길동"
const age = _.get(user, "profile.age", 0); // 0 (기본값)
// 중첩 속성 설정
const newUser = {};
_.set(newUser, "profile.settings.notifications", true);
// { profile: { settings: { notifications: true } } }
스마트 객체 병합
const defaultConfig = {
api: { timeout: 5000, retries: 3 },
ui: { theme: "light", language: "ko" }
};
const userConfig = {
api: { timeout: 8000 },
ui: { theme: "dark" }
};
// 깊은 병합 - 기본 설정 유지하며 사용자 설정 적용
const config = _.merge({}, defaultConfig, userConfig);
// {
// api: { timeout: 8000, retries: 3 },
// ui: { theme: "dark", language: "ko" }
// }
3. 컬렉션 처리의 전문가
const users = [
{ name: "홍길동", age: 30, active: true, department: "개발" },
{ name: "김철수", age: 25, active: false, department: "디자인" },
{ name: "이영희", age: 35, active: true, department: "개발" },
{ name: "박민수", age: 28, active: true, department: "마케팅" }
];
// 부서별 그룹화
const groupedByDept = _.groupBy(users, "department");
// {
// 개발: [{홍길동}, {이영희}],
// 디자인: [{김철수}],
// 마케팅: [{박민수}]
// }
// 활성 사용자의 평균 나이
const averageAge = _.meanBy(_.filter(users, "active"), "age");
// 특정 속성만 추출
const names = _.map(users, "name"); // ["홍길동", "김철수", "이영희", "박민수"]
const activeNames = _.map(_.filter(users, "active"), "name");
4. 함수 유틸리티의 마스터
성능 최적화 도구
// 디바운싱 - 검색 입력 최적화
const debouncedSearch = _.debounce((query) => {
console.log("검색:", query);
// API 호출 로직
}, 300);
// 스로틀링 - 스크롤 이벤트 최적화
const throttledScroll = _.throttle(() => {
console.log("스크롤 위치 업데이트");
// 위치 계산 로직
}, 100);
// 한 번만 실행되는 함수
const initializeApp = _.once(() => {
console.log("앱 초기화 - 한 번만 실행됨");
// 초기화 로직
});
지연 실행과 커링
// 지연 실행
_.delay(() => {
console.log("2초 후 실행");
}, 2000);
// 커링을 통한 함수 조합
const multiply = (a, b) => a * b;
const double = _.partial(multiply, 2);
const result = double(5); // 10
5. 강력한 체이닝
const salesData = [
{ date: "2024-01", amount: 1000, region: "서울" },
{ date: "2024-01", amount: 1500, region: "부산" },
{ date: "2024-02", amount: 2000, region: "서울" },
{ date: "2024-02", amount: 800, region: "부산" }
];
// 복잡한 데이터 처리를 체이닝으로 간단하게
const monthlySeoulTotal = _(salesData)
.filter({ region: "서울" })
.groupBy("date")
.mapValues(items => _.sumBy(items, "amount"))
.value();
// { "2024-01": 1000, "2024-02": 2000 }
6. 문자열 처리의 달인
// 케이스 변환 - API 응답 정규화에 유용
const apiResponse = {
"user_name": "홍길동",
"created_at": "2024-01-01",
"is_active": true
};
// 스네이크 케이스를 카멜 케이스로
const normalized = _.mapKeys(apiResponse, (value, key) => _.camelCase(key));
// { userName: "홍길동", createdAt: "2024-01-01", isActive: true }
// 문자열 조작
_.capitalize("hello world"); // "Hello world"
_.pad("42", 6, "0"); // "004200"
_.truncate("매우 긴 텍스트입니다", { length: 8 }); // "매우 긴 텍..."
성능 최적화 팁
선택적 Import로 번들 크기 줄이기
// ❌ 전체 라이브러리 import
import _ from "lodash";
// ✅ 필요한 함수만 import
import debounce from "lodash/debounce";
import cloneDeep from "lodash/cloneDeep";
import get from "lodash/get";
// ✅ 또는 구조 분해 import
import { debounce, cloneDeep, get } from "lodash";
webpack bundle analyzer 활용
npm install --save-dev webpack-bundle-analyzer
# 번들 크기 분석하여 불필요한 Lodash 함수 제거
Native JavaScript 대안
ES6+ 기능으로 대체 가능한 Lodash 함수들:
// Lodash vs Native 비교
_.map(arr, fn) → arr.map(fn)
_.filter(arr, fn) → arr.filter(fn)
_.find(arr, fn) → arr.find(fn)
_.includes(arr, val) → arr.includes(val)
_.assign(obj1, obj2) → Object.assign(obj1, obj2) 또는 {...obj1, ...obj2}
// 하지만 이런 함수들은 여전히 Lodash가 유용함
_.get(obj, "deep.nested.path", defaultValue)
_.cloneDeep(complexObject)
_.debounce(func, wait)
_.chunk(array, size)
언제 Lodash를 사용해야 할까?
사용하면 좋은 경우
- 복잡한 데이터 구조 조작이 필요한 프로젝트
- 크로스 브라우저 호환성이 중요한 경우
- 함수형 프로그래밍 스타일을 선호하는 팀
- 빠른 프로토타이핑이 필요한 경우
대안을 고려해야 하는 경우
- 번들 크기에 민감한 모바일 웹 앱
- 최신 브라우저만 지원하는 프로젝트
- 팀이 vanilla JavaScript를 선호하는 경우
- 단순한 배열/객체 조작만 필요한 경우
결론
Lodash는 JavaScript 개발에서 생산성과 코드 품질을 크게 향상시켜주는 강력한 도구입니다. 특히 복잡한 데이터 조작, 함수형 프로그래밍, 성능 최적화가 필요한 상황에서 그 진가를 발휘합니다.
하지만 현대 JavaScript의 발전으로 많은 기능들이 네이티브로 지원되고 있어, 선택적으로 활용하는 것이 중요합니다. 프로젝트의 요구사항과 팀의 선호도를 고려하여 적절히 도입하시기 바랍니다.
다음 학습 방향
- Lodash/FP: 함수형 프로그래밍에 특화된 Lodash 버전
- Ramda: Lodash 대안으로 주목받는 함수형 유틸리티 라이브러리
- RxJS: 반응형 프로그래밍을 위한 라이브러리