在 JavaScript 中,我们经常需要将多个对象合并为一个对象。在 ES6 中,我们可以使用 Object.assign() 方法来实现这个功能。但是,Object.assign() 方法只能复制对象的属性值,而不能复制属性的描述符。如果我们需要复制对象的属性描述符,例如属性的可枚举性、可配置性、可写性等等,我们需要使用 Object.getOwnPropertyDescriptors() 方法。
然而,使用 Object.getOwnPropertyDescriptors() 方法有一个缺点,就是它的返回值是一个包含所有属性描述符的对象。如果我们只需要获取对象的属性值,而不需要属性描述符,那么我们就需要再次遍历这个对象,提取属性值。这样做既浪费时间,又降低了代码的可读性。
在 ES8 中,我们可以使用 Object.values() 方法或者 valueOf 方法来解决这个问题。这两个方法都可以提取对象的属性值,并且不包含属性描述符。
Object.values() 方法
Object.values() 方法返回一个包含对象所有可枚举属性值的数组。例如:
const obj = { a: 1, b: 2, c: 3 }; const values = Object.values(obj); console.log(values); // [1, 2, 3]
我们可以使用这个方法来合并多个对象:
const obj1 = { a: 1, b: 2 }; const obj2 = { c: 3, d: 4 }; const obj3 = { e: 5, f: 6 }; const merged = Object.assign({}, ...[obj1, obj2, obj3].map(Object.entries).flat().map(([k, v]) => ({ [k]: v }))); console.log(merged); // { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }
上面的代码中,我们先将多个对象转换为一个包含键值对的数组,然后使用 flat() 方法将这个数组扁平化,最后使用 map() 方法将键值对数组转换为包含单个键值对的对象。最终,我们使用 Object.assign() 方法将所有的对象合并到一个新对象中。
这种方法的缺点是需要使用多个方法和高阶函数,代码比较冗长,可读性也不太好。
valueOf 方法
在 JavaScript 中,所有的对象都有一个 valueOf 方法,它返回对象的原始值。对于普通的对象,这个方法返回对象本身。但是,对于 Date 对象、RegExp 对象等等,这个方法返回的是对象的原始值。
我们可以使用 valueOf 方法来提取对象的属性值,例如:
const obj = { a: 1, b: 2, c: 3 }; const values = Object.keys(obj).map(key => obj[key].valueOf()); console.log(values); // [1, 2, 3]
上面的代码中,我们先使用 Object.keys() 方法获取对象的所有键名,然后使用 map() 方法遍历所有的键名,提取每个键名对应的属性值的原始值。
我们可以使用这个方法来合并多个对象:
const obj1 = { a: 1, b: 2 }; const obj2 = { c: 3, d: 4 }; const obj3 = { e: 5, f: 6 }; const merged = Object.assign({}, ...[obj1, obj2, obj3].map(obj => Object.keys(obj).reduce((acc, key) => ({ ...acc, [key]: obj[key].valueOf() }), {}))); console.log(merged); // { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }
上面的代码中,我们首先使用 map() 方法将多个对象转换为只包含属性值的对象,然后使用 reduce() 方法将所有的对象合并到一个新对象中。
这种方法的优点是代码比较简洁,可读性比较好。
总结
在 ES8 中,我们可以使用 Object.values() 方法或者 valueOf 方法来提取对象的属性值,并且不包含属性描述符。这两种方法都可以用于合并多个对象,但是使用 valueOf 方法比较简洁,可读性也比较好。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6583d212d2f5e1655de9c34a