Lodash Complete Guide
이 글의 핵심
Lodash is the most popular JavaScript utility library. It provides functions for arrays, objects, strings, functions, and more — making JavaScript development easier and more consistent.
Introduction
Lodash is a modern JavaScript utility library delivering modularity, performance, and extras. It makes working with arrays, objects, strings, functions, and numbers easier and more consistent.
Why Lodash?
Native JavaScript:
// Deep clone (doesn't work properly)
const clone = JSON.parse(JSON.stringify(obj)); // Loses functions, dates
// Debounce (complex to implement)
let timeout;
function debounce(fn, delay) {
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => fn(...args), delay);
};
}
With Lodash:
// Deep clone
const clone = _.cloneDeep(obj);
// Debounce
const debouncedFn = _.debounce(fn, delay);
Real-World Adoption
Lodash is the most widely-used JavaScript utility library in the world:
Market Dominance:
- 140+ million weekly npm downloads (April 2026) - the most downloaded npm package after core Node.js modules
- 59,000+ GitHub stars - massive community adoption
- Used in 14+ million public GitHub repositories - more than any other JavaScript utility library
- Depended on by 95% of top 5,000 npm packages - industry standard
Enterprise Usage:
- Facebook: Uses Lodash extensively in React codebase and internal tools
- Google: Employs Lodash in Angular, Google Cloud Console, and Firebase tools
- Microsoft: Integrated into TypeScript compiler tools and VS Code extensions
- Netflix: Powers frontend utilities and data transformation pipelines
- Airbnb: Core part of their JavaScript style guide and codebase
Why Lodash Dominates:
- Battle-tested: In production since 2012, with billions of downloads
- Performance: Optimized implementations often faster than native alternatives
- Consistency: Works the same across all browsers and Node.js versions
- Deep operations: Handles nested objects/arrays better than native methods
- Functional programming: Supports FP patterns (curry, compose, pipe)
- Tree-shakeable: Modern bundlers can eliminate unused functions
Key Statistics:
- 500+ utility functions covering arrays, objects, strings, numbers, functions
- 4KB gzipped for common functions (debounce, throttle, cloneDeep)
- TypeScript support: Full type definitions maintained
- Zero dependencies: No external packages required
Modern JavaScript vs Lodash:
While ES2015+ added many array methods (map, filter, find), Lodash still excels at:
- Deep cloning (
_.cloneDeep) - Debounce/throttle (
_.debounce,_.throttle) - Deep object operations (
_.get,_.set,_.merge) - Complex array operations (
_.chunk,_.difference,_.groupBy) - Functional composition (
_.flow,_.curry)
Alternatives:
- Ramda: Functional programming focus, smaller but different API
- Underscore: Lodash predecessor, less features
- Native ES6+: Good for simple operations, but lacks deep utilities
Lodash remains essential in 2026 for production applications requiring robust, tested utilities for complex data transformations.
1. Installation
# npm
npm install lodash
# yarn
yarn add lodash
# CDN (browser)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
Import Methods
// Import entire library
import _ from 'lodash';
// Import individual functions (recommended for tree-shaking)
import debounce from 'lodash/debounce';
import cloneDeep from 'lodash/cloneDeep';
// CommonJS
const _ = require('lodash');
const debounce = require('lodash/debounce');
2. Array Methods
Map, Filter, Reduce
const users = [
{ id: 1, name: 'Alice', age: 30, active: true },
{ id: 2, name: 'Bob', age: 25, active: false },
{ id: 3, name: 'Charlie', age: 35, active: true },
];
// Map
_.map(users, 'name'); // ['Alice', 'Bob', 'Charlie']
_.map(users, user => user.age * 2); // [60, 50, 70]
// Filter
_.filter(users, { active: true }); // Active users
_.filter(users, user => user.age > 30); // Age > 30
// Find
_.find(users, { name: 'Alice' }); // First match
_.findLast(users, { active: true }); // Last match
// Reduce
_.reduce(users, (sum, user) => sum + user.age, 0); // Total age: 90
Unique, Flatten, Chunk
// Unique
_.uniq([1, 2, 2, 3, 3, 4]); // [1, 2, 3, 4]
_.uniqBy([{ x: 1 }, { x: 2 }, { x: 1 }], 'x'); // [{ x: 1 }, { x: 2 }]
// Flatten
_.flatten([1, [2, [3, [4]]]]); // [1, 2, [3, [4]]]
_.flattenDeep([1, [2, [3, [4]]]]); // [1, 2, 3, 4]
// Chunk (split into groups)
_.chunk([1, 2, 3, 4, 5, 6], 2); // [[1, 2], [3, 4], [5, 6]]
_.chunk(['a', 'b', 'c', 'd'], 3); // [['a', 'b', 'c'], ['d']]
// Compact (remove falsy values)
_.compact([0, 1, false, 2, '', 3, null, undefined]); // [1, 2, 3]
Difference, Intersection, Union
const arr1 = [1, 2, 3];
const arr2 = [2, 3, 4];
// Difference (in arr1 but not arr2)
_.difference(arr1, arr2); // [1]
// Intersection (in both)
_.intersection(arr1, arr2); // [2, 3]
// Union (all unique values)
_.union(arr1, arr2); // [1, 2, 3, 4]
// With objects
const users1 = [{ id: 1 }, { id: 2 }];
const users2 = [{ id: 2 }, { id: 3 }];
_.differenceBy(users1, users2, 'id'); // [{ id: 1 }]
_.intersectionBy(users1, users2, 'id'); // [{ id: 2 }]
Sorting
const users = [
{ name: 'Charlie', age: 35 },
{ name: 'Alice', age: 30 },
{ name: 'Bob', age: 25 },
];
// Sort by single property
_.sortBy(users, 'age');
// [{ name: 'Bob', age: 25 }, { name: 'Alice', age: 30 }, { name: 'Charlie', age: 35 }]
// Sort by multiple properties
_.sortBy(users, ['age', 'name']);
// Sort with custom order
_.orderBy(users, ['age'], ['desc']);
// [{ name: 'Charlie', age: 35 }, ...]
Take, Drop, Sample
const arr = [1, 2, 3, 4, 5];
// Take first n
_.take(arr, 2); // [1, 2]
_.takeRight(arr, 2); // [4, 5]
// Drop first n
_.drop(arr, 2); // [3, 4, 5]
_.dropRight(arr, 2); // [1, 2, 3]
// Random sample
_.sample(arr); // Random element
_.sampleSize(arr, 2); // 2 random elements
// Shuffle
_.shuffle([1, 2, 3, 4, 5]); // Random order
3. Object Methods
Get, Set, Has
const user = {
name: 'Alice',
address: {
city: 'New York',
zip: '10001',
},
};
// Get (safe nested access)
_.get(user, 'address.city'); // 'New York'
_.get(user, 'address.country', 'USA'); // 'USA' (default)
_.get(user, 'profile.bio'); // undefined
// Set (create nested path)
_.set(user, 'profile.bio', 'Developer');
// { name: 'Alice', address: {...}, profile: { bio: 'Developer' } }
// Has
_.has(user, 'address.city'); // true
_.has(user, 'address.country'); // false
Pick, Omit
const user = {
id: 1,
name: 'Alice',
email: 'alice@example.com',
password: 'secret',
role: 'admin',
};
// Pick (select properties)
_.pick(user, ['id', 'name', 'email']);
// { id: 1, name: 'Alice', email: 'alice@example.com' }
// Omit (exclude properties)
_.omit(user, ['password', 'role']);
// { id: 1, name: 'Alice', email: 'alice@example.com' }
Merge, Assign
const obj1 = { a: 1, b: { x: 1 } };
const obj2 = { b: { y: 2 }, c: 3 };
// Merge (deep)
_.merge(obj1, obj2);
// { a: 1, b: { x: 1, y: 2 }, c: 3 }
// Assign (shallow)
_.assign({}, obj1, obj2);
// { a: 1, b: { y: 2 }, c: 3 }
Keys, Values, Entries
const obj = { a: 1, b: 2, c: 3 };
// Keys
_.keys(obj); // ['a', 'b', 'c']
// Values
_.values(obj); // [1, 2, 3]
// Entries (key-value pairs)
_.toPairs(obj); // [['a', 1], ['b', 2], ['c', 3]]
// From entries
_.fromPairs([['a', 1], ['b', 2]]); // { a: 1, b: 2 }
Clone
const obj = {
name: 'Alice',
address: { city: 'NYC' },
hobbies: ['coding', 'reading'],
};
// Shallow clone
const shallow = _.clone(obj);
shallow.address.city = 'LA'; // Affects original!
// Deep clone
const deep = _.cloneDeep(obj);
deep.address.city = 'LA'; // Doesn't affect original
4. Collection Methods
const users = [
{ name: 'Alice', age: 30, active: true },
{ name: 'Bob', age: 25, active: false },
{ name: 'Charlie', age: 35, active: true },
];
// Group by
_.groupBy(users, 'active');
// {
// true: [{ name: 'Alice', ... }, { name: 'Charlie', ... }],
// false: [{ name: 'Bob', ... }]
// }
// Count by
_.countBy(users, 'active'); // { true: 2, false: 1 }
// Key by (index by property)
_.keyBy(users, 'name');
// {
// Alice: { name: 'Alice', ... },
// Bob: { name: 'Bob', ... },
// Charlie: { name: 'Charlie', ... }
// }
// Partition (split by condition)
_.partition(users, { active: true });
// [[active users], [inactive users]]
5. Function Utilities
Debounce
// Debounce (wait until user stops typing)
const search = _.debounce((query) => {
console.log('Searching for:', query);
}, 300);
// User types: a, ab, abc
// Only searches once after 300ms of no typing
// Cancel pending debounce
search.cancel();
// Execute immediately
search.flush();
Throttle
// Throttle (execute at most once per interval)
const handleScroll = _.throttle(() => {
console.log('Scrolling');
}, 100);
window.addEventListener('scroll', handleScroll);
// Execute at most once per 100ms
// Cancel
handleScroll.cancel();
Once
// Execute only once
const initialize = _.once(() => {
console.log('Initialized');
});
initialize(); // Logs: "Initialized"
initialize(); // Does nothing
initialize(); // Does nothing
Memoize
// Cache function results
const fibonacci = _.memoize((n) => {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
});
fibonacci(40); // First call: slow
fibonacci(40); // Cached: instant
// Custom cache key
const getUser = _.memoize(
async (id) => {
const response = await fetch(`/users/${id}`);
return response.json();
},
(id) => `user-${id}` // Cache key
);
Curry
// Curry (partial application)
const add = (a, b, c) => a + b + c;
const curriedAdd = _.curry(add);
curriedAdd(1)(2)(3); // 6
curriedAdd(1, 2)(3); // 6
curriedAdd(1)(2, 3); // 6
// Useful for reusable functions
const add5 = curriedAdd(5);
add5(10, 15); // 30
6. String Methods
// Case conversion
_.camelCase('hello world'); // 'helloWorld'
_.snakeCase('helloWorld'); // 'hello_world'
_.kebabCase('helloWorld'); // 'hello-world'
_.startCase('hello world'); // 'Hello World'
// Truncate
_.truncate('This is a very long string', { length: 15 });
// 'This is a ve...'
// Pad
_.pad('hi', 8); // ' hi '
_.padStart('5', 3, '0'); // '005'
_.padEnd('5', 3, '0'); // '500'
// Trim
_.trim(' hello '); // 'hello'
_.trimStart(' hello '); // 'hello '
_.trimEnd(' hello '); // ' hello'
7. Number Methods
// Random
_.random(1, 10); // Random int between 1 and 10
_.random(1.5, 5.5, true); // Random float
// Clamp (constrain to range)
_.clamp(10, 0, 5); // 5
_.clamp(-5, 0, 10); // 0
_.clamp(3, 0, 10); // 3
// In range
_.inRange(3, 2, 4); // true
_.inRange(5, 8); // true (0 to 8)
8. Real-World Examples
API Request with Debounce
import debounce from 'lodash/debounce';
import axios from 'axios';
const searchAPI = async (query) => {
const response = await axios.get('/api/search', {
params: { q: query }
});
return response.data;
};
// Debounce to avoid excessive API calls
const debouncedSearch = debounce(searchAPI, 300);
// React example
function SearchInput() {
const [results, setResults] = useState([]);
const handleChange = async (e) => {
const query = e.target.value;
if (query.length > 2) {
const data = await debouncedSearch(query);
setResults(data);
}
};
return <input onChange={handleChange} />;
}
Data Transformation
import { groupBy, mapValues, sortBy } from 'lodash';
const orders = [
{ id: 1, customer: 'Alice', amount: 100, status: 'completed' },
{ id: 2, customer: 'Bob', amount: 50, status: 'pending' },
{ id: 3, customer: 'Alice', amount: 200, status: 'completed' },
];
// Group by customer and sum amounts
const customerTotals = mapValues(
groupBy(orders, 'customer'),
(orders) => orders.reduce((sum, order) => sum + order.amount, 0)
);
// { Alice: 300, Bob: 50 }
// Get top customers
const topCustomers = sortBy(
Object.entries(customerTotals),
([_, amount]) => -amount
);
// [['Alice', 300], ['Bob', 50]]
Safe Object Access
import get from 'lodash/get';
// API response
const response = {
data: {
user: {
profile: {
email: 'alice@example.com'
}
}
}
};
// Safe access (no errors if path doesn't exist)
const email = get(response, 'data.user.profile.email');
const phone = get(response, 'data.user.profile.phone', 'N/A');
// Instead of:
// const email = response?.data?.user?.profile?.email;
9. TypeScript Support
import { debounce, cloneDeep } from 'lodash';
interface User {
id: number;
name: string;
}
const users: User[] = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
];
// Type-safe clone
const cloned: User[] = cloneDeep(users);
// Type-safe debounce
const handleSearch = debounce((query: string) => {
console.log(query);
}, 300);
10. Bundle Size Optimization
// Bad: imports entire library (~70KB)
import _ from 'lodash';
_.debounce(fn, 300);
// Good: import only what you need
import debounce from 'lodash/debounce';
debounce(fn, 300);
// Even better: use lodash-es for tree-shaking
import { debounce } from 'lodash-es';
11. Performance Tips
1. Chain Operations
// Good: chain for efficiency
_.chain(users)
.filter({ active: true })
.sortBy('age')
.take(10)
.value();
// Bad: multiple operations
let result = _.filter(users, { active: true });
result = _.sortBy(result, 'age');
result = _.take(result, 10);
2. Reuse Functions
// Good: create once, use many times
const debouncedSearch = _.debounce(search, 300);
// Bad: create new function every time
onClick={() => _.debounce(search, 300)()}
Summary
Lodash simplifies JavaScript development:
- Array/Object manipulation
- Function utilities (debounce, throttle, memoize)
- Deep cloning and safe object access
- String formatting
- Cross-browser consistency
Key Takeaways:
- Import individual functions to reduce bundle size
- Use debounce/throttle for performance
- Deep clone with _.cloneDeep
- Safe nested access with _.get
- Group/transform data with collection methods
Next Steps:
- Compare Ramda
- Learn JavaScript
- Optimize with Webpack
Resources:
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Complete Lodash guide for JavaScript utilities.
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
- date-fns Complete Guide
- C++ vector reserve vs resize: When to Use Which
- C++ Constant Initialization |
constexpr·constinit
Keywords Covered in This Article (Related Search Terms)
This article covers Lodash, JavaScript, Utilities, Arrays, Objects, Functions.