Lodash provides rich object operation methods. Here is a detailed answer about Lodash object operations:
Common Lodash Object Operation Methods
1. Object Property Access
_.get(object, path, [defaultValue])
Safely gets object properties, supporting nested paths.
javascriptvar object = { 'a': [{ 'b': { 'c': 3 } }] }; _.get(object, 'a[0].b.c'); // => 3 _.get(object, ['a', '0', 'b', 'c']); // => 3 _.get(object, 'a.b.c', 'default'); // => 'default' // Real application: Safe access to nested API responses function getUserEmail(user) { return _.get(user, 'profile.contact.email', 'no-email@example.com'); } const user = { profile: { contact: { email: 'john@example.com' } } }; console.log(getUserEmail(user)); // => 'john@example.com' console.log(getUserEmail({})); // => 'no-email@example.com'
_.has(object, path)
Checks if an object contains the specified property path.
javascriptvar object = { 'a': { 'b': 2 } }; _.has(object, 'a'); // => true _.has(object, 'a.b'); // => true _.has(object, ['a', 'b']); // => true _.has(object, 'a.b.c'); // => false // Real application: Check if configuration item exists function hasConfig(config, path) { return _.has(config, path); } const config = { api: { baseUrl: 'https://api.example.com', timeout: 5000 } }; console.log(hasConfig(config, 'api.baseUrl')); // => true console.log(hasConfig(config, 'api.retry')); // => false
_.hasIn(object, path)
Similar to _.has, but checks the prototype chain.
javascriptvar object = _.create({ 'a': _.create({ 'b': 2 }) }); _.hasIn(object, 'a'); // => true _.hasIn(object, 'a.b'); // => true _.hasIn(object, ['a', 'b']); // => true _.hasIn(object, 'a.b.c'); // => false
2. Object Property Setting
_.set(object, path, value)
Sets the value of an object property, supporting nested paths.
javascriptvar object = { 'a': [{ 'b': { 'c': 3 } }] }; _.set(object, 'a[0].b.c', 4); console.log(object.a[0].b.c); // => 4 _.set(object, ['x', '0', 'y', 'z'], 5); console.log(object.x[0].y.z); // => 5 // Real application: Dynamically set configuration function setConfig(config, path, value) { return _.set(config, path, value); } const config = {}; setConfig(config, 'api.baseUrl', 'https://api.example.com'); setConfig(config, 'api.timeout', 5000); console.log(config); // => { api: { baseUrl: 'https://api.example.com', timeout: 5000 } }
_.setWith(object, path, value, [customizer])
Similar to _.set, but allows customizing how values are set.
javascriptvar object = {}; _.setWith(object, '[0][1]', 'a', Object); console.log(object); // => { '0': { '1': 'a' } }
3. Object Property Deletion
_.unset(object, path)
Deletes object property paths.
javascriptvar object = { 'a': [{ 'b': { 'c': 7 } }] }; _.unset(object, 'a[0].b.c'); console.log(object); // => { 'a': [{ 'b': {} }] } // Real application: Delete configuration items function removeConfig(config, path) { return _.unset(config, path); } const config = { api: { baseUrl: 'https://api.example.com', timeout: 5000, retry: 3 } }; removeConfig(config, 'api.retry'); console.log(config); // => { api: { baseUrl: 'https://api.example.com', timeout: 5000 } }
4. Object Merging
_.assign(object, [sources])
Assigns properties of source objects to the target object.
javascriptfunction Foo() { this.a = 1; } function Bar() { this.c = 3; } Foo.prototype.b = 2; Bar.prototype.d = 4; _.assign({ 'a': 0 }, new Foo, new Bar); // => { 'a': 1, 'c': 3 } // Real application: Merge configuration objects function mergeConfigs(baseConfig, userConfig) { return _.assign({}, baseConfig, userConfig); } const baseConfig = { theme: 'light', language: 'en' }; const userConfig = { theme: 'dark', fontSize: 16 }; const merged = mergeConfigs(baseConfig, userConfig); // => { theme: 'dark', language: 'en', fontSize: 16 }
_.merge(object, [sources])
Recursively merges objects.
javascriptvar object = { 'a': [{ 'b': 2 }, { 'd': 4 }] }; var other = { 'a': [{ 'c': 3 }, { 'e': 5 }] }; _.merge(object, other); // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } // Real application: Deep merge configuration function deepMergeConfigs(baseConfig, userConfig) { return _.merge({}, baseConfig, userConfig); } const baseConfig = { api: { baseUrl: 'https://api.example.com', timeout: 5000 } }; const userConfig = { api: { timeout: 3000, retry: 3 } }; const merged = deepMergeConfigs(baseConfig, userConfig); // => { // api: { // baseUrl: 'https://api.example.com', // timeout: 3000, // retry: 3 // } // }
_.mergeWith(object, sources, customizer)
Similar to _.merge, but allows customizing merge behavior.
javascriptfunction customizer(objValue, srcValue) { if (_.isArray(objValue)) { return objValue.concat(srcValue); } } var object = { 'fruits': ['apple'], 'vegetables': ['beet'] }; var other = { 'fruits': ['banana'], 'vegetables': ['carrot'] }; _.mergeWith(object, other, customizer); // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
5. Object Property Selection
_.pick(object, [props])
Creates an object composed of the given properties.
javascriptvar object = { 'a': 1, 'b': '2', 'c': 3 }; _.pick(object, ['a', 'c']); // => { 'a': 1, 'c': 3 } _.pick(object, 'a', 'c'); // => { 'a': 1, 'c': 3 } // Real application: Extract user information function extractUserInfo(user) { return _.pick(user, ['id', 'name', 'email']); } const user = { id: 1, name: 'John Doe', email: 'john@example.com', password: 'secret', createdAt: '2024-01-01' }; const userInfo = extractUserInfo(user); // => { id: 1, name: 'John Doe', email: 'john@example.com' }
_.pickBy(object, [predicate])
Creates an object composed of properties that satisfy the condition.
javascriptvar object = { 'a': 1, 'b': '2', 'c': 3 }; _.pickBy(object, _.isNumber); // => { 'a': 1, 'c': 3 } // Real application: Filter object properties function filterObject(obj, predicate) { return _.pickBy(obj, predicate); } const data = { name: 'John', age: 30, email: 'john@example.com', phone: null, address: undefined }; const filtered = filterObject(data, value => value != null); // => { name: 'John', age: 30, email: 'john@example.com' }
_.omit(object, [props])
Creates an object excluding the given properties.
javascriptvar object = { 'a': 1, 'b': '2', 'c': 3 }; _.omit(object, ['a', 'c']); // => { 'b': '2' } // Real application: Exclude sensitive information function sanitizeUser(user) { return _.omit(user, ['password', 'token', 'secret']); } const user = { id: 1, name: 'John Doe', email: 'john@example.com', password: 'secret', token: 'abc123' }; const sanitized = sanitizeUser(user); // => { id: 1, name: 'John Doe', email: 'john@example.com' }
_.omitBy(object, [predicate])
Creates an object excluding properties that satisfy the condition.
javascriptvar object = { 'a': 1, 'b': '2', 'c': 3 }; _.omitBy(object, _.isNumber); // => { 'b': '2' }
6. Object Transformation
_.keys(object)
Creates an array of the object's own enumerable property names.
javascriptfunction Foo() { this.a = 1; this.b = 2; } Foo.prototype.c = 3; _.keys(new Foo); // => ['a', 'b'] (iteration order is not guaranteed) _.keys('hi'); // => ['0', '1']
_.values(object)
Creates an array of the object's own enumerable property values.
javascriptfunction Foo() { this.a = 1; this.b = 2; } Foo.prototype.c = 3; _.values(new Foo); // => [1, 2] (iteration order is not guaranteed) _.values('hi'); // => ['h', 'i']
_.toPairs(object)
Creates an array of the object's own enumerable string keyed property key-value pairs.
javascript_.toPairs({ 'a': 1, 'b': 2 }); // => [['a', 1], ['b', 2]] // Real application: Convert object to array function objectToArray(obj) { return _.toPairs(obj); } const config = { theme: 'dark', language: 'en', fontSize: 16 }; const configArray = objectToArray(config); // => [['theme', 'dark'], ['language', 'en'], ['fontSize', 16]]
_.fromPairs(pairs)
Reverse operation of _.toPairs.
javascript_.fromPairs([['a', 1], ['b', 2]]); // => { 'a': 1, 'b': 2 } // Real application: Create object from array function arrayToObject(pairs) { return _.fromPairs(pairs); } const configArray = [['theme', 'dark'], ['language', 'en']]; const config = arrayToObject(configArray); // => { theme: 'dark', language: 'en' }
7. Object Iteration
_.forOwn(object, [iteratee])
Iterates over own enumerable string keyed properties of an object.
javascriptfunction Foo() { this.a = 1; this.b = 2; } Foo.prototype.c = 3; _.forOwn(new Foo, function(value, key) { console.log(key); }); // => Logs 'a' then 'b' (iteration order is not guaranteed)
_.forIn(object, [iteratee])
Iterates over own and inherited enumerable string keyed properties of an object.
javascriptfunction Foo() { this.a = 1; this.b = 2; } Foo.prototype.c = 3; _.forIn(new Foo, function(value, key) { console.log(key); }); // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed)
8. Object Checking
_.isEmpty(value)
Checks if a value is empty.
javascript_.isEmpty(null); // => true _.isEmpty(true); // => true _.isEmpty(1); // => true _.isEmpty([1, 2, 3]); // => false _.isEmpty({ 'a': 1 }); // => false // Real application: Check if object is empty function isObjectEmpty(obj) { return _.isEmpty(obj); } console.log(isObjectEmpty({})); // => true console.log(isObjectEmpty({ a: 1 })); // => false
_.isEqual(value, other)
Performs a deep comparison between two values to see if they are equal.
javascriptvar object = { 'a': 1 }; var other = { 'a': 1 }; _.isEqual(object, other); // => true object === other; // => false // Real application: Compare two objects function areObjectsEqual(obj1, obj2) { return _.isEqual(obj1, obj2); } const user1 = { id: 1, name: 'John' }; const user2 = { id: 1, name: 'John' }; const user3 = { id: 2, name: 'Jane' }; console.log(areObjectsEqual(user1, user2)); // => true console.log(areObjectsEqual(user1, user3)); // => false
_.isPlainObject(value)
Checks if a value is a plain object.
javascriptfunction Foo() { this.a = 1; } _.isPlainObject(new Foo); // => false _.isPlainObject([1, 2, 3]); // => false _.isPlainObject({ 'x': 0, 'y': 0 }); // => true _.isPlainObject(Object.create(null)); // => true
9. Object Cloning
_.clone(value)
Creates a shallow clone of value.
javascriptvar objects = [{ 'a': 1 }, { 'b': 2 }]; var shallow = _.clone(objects); console.log(shallow[0] === objects[0]); // => true
_.cloneDeep(value)
Creates a deep clone of value.
javascriptvar objects = [{ 'a': 1 }, { 'b': 2 }]; var deep = _.cloneDeep(objects); console.log(deep[0] === objects[0]); // => false // Real application: Deep copy object function deepCopy(obj) { return _.cloneDeep(obj); } const original = { user: { name: 'John', profile: { email: 'john@example.com' } } }; const copy = deepCopy(original); copy.user.name = 'Jane'; console.log(original.user.name); // => 'John' (original object is not affected)
10. Object Transformation Utilities
_.mapKeys(object, [iteratee])
Creates an object with keys as the result of the iteratee function.
javascript_.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { return key + value; }); // => { 'a1': 1, 'b2': 2 }
_.mapValues(object, [iteratee])
Creates an object with values as the result of the iteratee function.
javascriptvar users = { 'fred': { 'user': 'fred', 'age': 40 }, 'pebbles': { 'user': 'pebbles', 'age': 1 } }; _.mapValues(users, function(o) { return o.age; }); // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) // Real application: Transform object values function transformObjectValues(obj, transformFn) { return _.mapValues(obj, transformFn); } const prices = { apple: 1.99, banana: 0.99, orange: 2.49 }; const formattedPrices = transformObjectValues(prices, price => `$${price.toFixed(2)}`); // => { apple: '$1.99', banana: '$0.99', orange: '$2.49' }
Real-World Application Examples
Configuration Manager
javascriptclass ConfigManager { constructor(baseConfig) { this.config = _.cloneDeep(baseConfig); } get(path, defaultValue) { return _.get(this.config, path, defaultValue); } set(path, value) { return _.set(this.config, path, value); } merge(userConfig) { this.config = _.merge({}, this.config, userConfig); return this; } getAll() { return _.cloneDeep(this.config); } pick(keys) { return _.pick(this.config, keys); } omit(keys) { return _.omit(this.config, keys); } } const baseConfig = { api: { baseUrl: 'https://api.example.com', timeout: 5000 }, theme: { primary: '#007bff', secondary: '#6c757d' } }; const configManager = new ConfigManager(baseConfig); configManager.set('api.retry', 3); configManager.merge({ theme: { primary: '#28a745' } }); console.log(configManager.get('api.timeout')); // => 5000 console.log(configManager.get('theme.primary')); // => '#28a745'
Data Transformer
javascriptclass DataTransformer { static transformUser(rawUser) { return _.chain(rawUser) .pick(['id', 'name', 'email', 'profile']) .mapValues(value => { if (_.isString(value)) return _.trim(value); return value; }) .set('fullName', _.get(rawUser, 'profile.firstName') + ' ' + _.get(rawUser, 'profile.lastName')) .omitBy(_.isNil) .value(); } static sanitizeResponse(response) { return _.chain(response) .get('data', {}) .omit(['password', 'token', 'secret']) .mapKeys((value, key) => _.camelCase(key)) .value(); } } const rawUser = { id: 1, name: ' John Doe ', email: 'john@example.com', profile: { firstName: 'John', lastName: 'Doe', age: 30 }, password: 'secret' }; const transformedUser = DataTransformer.transformUser(rawUser); // => { // id: 1, // name: 'John Doe', // email: 'john@example.com', // profile: { firstName: 'John', lastName: 'Doe', age: 30 }, // fullName: 'John Doe' // }
Summary
Lodash provides rich object operation methods covering object property access, setting, deletion, merging, selection, transformation, iteration, checking, and cloning. Mastering these methods can greatly improve the efficiency of object processing and code readability. In actual development, it's recommended to choose appropriate methods based on specific needs and make full use of method chaining to simplify code.