乐闻世界logo
搜索文章和话题

Lodash中有哪些常用的对象操作方法?请举例说明它们的用法

2月18日 22:02

Lodash提供了丰富的对象操作方法,以下是Lodash对象操作的详细解答:

Lodash常用对象操作方法

1. 对象属性访问

_.get(object, path, [defaultValue])

安全地获取对象属性,支持嵌套路径。

javascript
var 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' // 实际应用:安全访问嵌套API响应 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)

检查对象是否包含指定的属性路径。

javascript
var object = { 'a': { 'b': 2 } }; _.has(object, 'a'); // => true _.has(object, 'a.b'); // => true _.has(object, ['a', 'b']); // => true _.has(object, 'a.b.c'); // => false // 实际应用:检查配置项是否存在 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)

类似于_.has,但会检查原型链。

javascript
var 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. 对象属性设置

_.set(object, path, value)

设置对象属性的值,支持嵌套路径。

javascript
var 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 // 实际应用:动态设置配置 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])

类似于_.set,但可以自定义如何设置值。

javascript
var object = {}; _.setWith(object, '[0][1]', 'a', Object); console.log(object); // => { '0': { '1': 'a' } }

3. 对象属性删除

_.unset(object, path)

删除对象属性路径。

javascript
var object = { 'a': [{ 'b': { 'c': 7 } }] }; _.unset(object, 'a[0].b.c'); console.log(object); // => { 'a': [{ 'b': {} }] } // 实际应用:删除配置项 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. 对象合并

_.assign(object, [sources])

将源对象的属性分配到目标对象。

javascript
function 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 } // 实际应用:合并配置对象 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])

递归合并对象。

javascript
var 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 }] } // 实际应用:深度合并配置 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)

类似于_.merge,但可以自定义合并行为。

javascript
function 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. 对象属性选择

_.pick(object, [props])

创建一个由给定属性组成的对象。

javascript
var object = { 'a': 1, 'b': '2', 'c': 3 }; _.pick(object, ['a', 'c']); // => { 'a': 1, 'c': 3 } _.pick(object, 'a', 'c'); // => { 'a': 1, 'c': 3 } // 实际应用:提取用户信息 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])

创建一个由满足条件的属性组成的对象。

javascript
var object = { 'a': 1, 'b': '2', 'c': 3 }; _.pickBy(object, _.isNumber); // => { 'a': 1, 'c': 3 } // 实际应用:过滤对象属性 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])

创建一个排除给定属性的对象。

javascript
var object = { 'a': 1, 'b': '2', 'c': 3 }; _.omit(object, ['a', 'c']); // => { 'b': '2' } // 实际应用:排除敏感信息 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])

创建一个排除满足条件属性的对象。

javascript
var object = { 'a': 1, 'b': '2', 'c': 3 }; _.omitBy(object, _.isNumber); // => { 'b': '2' }

6. 对象转换

_.keys(object)

创建一个对象自身可枚举属性名的数组。

javascript
function 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)

创建一个对象自身可枚举属性值的数组。

javascript
function 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)

创建一个对象自身可枚举属性的键值对数组。

javascript
_.toPairs({ 'a': 1, 'b': 2 }); // => [['a', 1], ['b', 2]] // 实际应用:转换对象为数组 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)

_.toPairs的反向操作。

javascript
_.fromPairs([['a', 1], ['b', 2]]); // => { 'a': 1, 'b': 2 } // 实际应用:从数组创建对象 function arrayToObject(pairs) { return _.fromPairs(pairs); } const configArray = [['theme', 'dark'], ['language', 'en']]; const config = arrayToObject(configArray); // => { theme: 'dark', language: 'en' }

7. 对象遍历

_.forOwn(object, [iteratee])

遍历对象自身的可枚举属性。

javascript
function 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])

遍历对象自身和继承的可枚举属性。

javascript
function 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. 对象检查

_.isEmpty(value)

检查值是否为空。

javascript
_.isEmpty(null); // => true _.isEmpty(true); // => true _.isEmpty(1); // => true _.isEmpty([1, 2, 3]); // => false _.isEmpty({ 'a': 1 }); // => false // 实际应用:检查对象是否为空 function isObjectEmpty(obj) { return _.isEmpty(obj); } console.log(isObjectEmpty({})); // => true console.log(isObjectEmpty({ a: 1 })); // => false

_.isEqual(value, other)

深度比较两个值是否相等。

javascript
var object = { 'a': 1 }; var other = { 'a': 1 }; _.isEqual(object, other); // => true object === other; // => false // 实际应用:比较两个对象 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)

检查值是否是普通对象。

javascript
function 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. 对象克隆

_.clone(value)

浅克隆值。

javascript
var objects = [{ 'a': 1 }, { 'b': 2 }]; var shallow = _.clone(objects); console.log(shallow[0] === objects[0]); // => true

_.cloneDeep(value)

深度克隆值。

javascript
var objects = [{ 'a': 1 }, { 'b': 2 }]; var deep = _.cloneDeep(objects); console.log(deep[0] === objects[0]); // => false // 实际应用:深拷贝对象 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' (原对象未受影响)

10. 对象转换工具

_.mapKeys(object, [iteratee])

创建一个对象,键是迭代器函数的结果。

javascript
_.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { return key + value; }); // => { 'a1': 1, 'b2': 2 }

_.mapValues(object, [iteratee])

创建一个对象,值是迭代器函数的结果。

javascript
var 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) // 实际应用:转换对象值 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' }

实际应用示例

配置管理器

javascript
class 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'

数据转换器

javascript
class 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' // }

总结

Lodash提供了丰富的对象操作方法,涵盖了对象属性访问、设置、删除、合并、选择、转换、遍历、检查和克隆等各个方面。掌握这些方法可以大大提高对象处理的效率和代码的可读性。在实际开发中,建议根据具体需求选择合适的方法,并充分利用链式调用来简化代码。

标签:Lodash