ES9(ECMAScript 2018)正式发布后,其中的一个新增特性就是 Object spread operator(对象展开符)。这个特性在 React 社区已经比较流行了,但是它的强大功能也可以在纯粹的 JavaScript 中发挥出来。在本文中,我们将深入介绍 Object spread operator 的用法和相关技巧。
对象展开符的用法
对象展开符(...
)是一个非常有用的运算符,特别是在对象和数组的处理中。在对象中,使用展开符可以很方便地实现对象的合并。我们看下面这个例子:
const obj1 = { a: 1, b: 2 }; const obj2 = { c: 3, d: 4 }; const mergedObj = { ...obj1, ...obj2 };
展开符将 obj1
和 obj2
的所有属性,包括 a
、b
、c
和 d
,都合并到了新对象 mergedObj
中。此时 mergedObj
的值为 { a: 1, b: 2, c: 3, d: 4 }
。
展开符也可以用来增加或改变对象的属性。下面的代码演示了如何添加一个新属性和改变一个现有属性:
const obj1 = { a: 1 }; const obj2 = { ...obj1, b: 2, a: 3 };
这里把一个新属性 b
增加到了对象中,同时还改变了属性 a
的值,因为后面的值覆盖了前面的值。此时 obj2
的值为 { a: 3, b: 2 }
。
深入理解展开符
展开符的运算符 ...
有时候可能会让人感到神秘。其实它的真正作用是“提取出符合要求的属性值”,也就是“展开”对象中的所有属性,并把它们组合成一个新的对象。
下面这个例子,是一个简单的数组展开:
const arr1 = [1, 2, 3]; const arr2 = [...arr1, 4, 5]; console.log(arr2); // [1, 2, 3, 4, 5]
再看下面的例子:
const obj1 = { a: 1, b: 2 }; const obj2 = { c: 3, d: 4 }; const obj3 = { ...obj1, ...obj2 };
我们可以使用 Object.assign()
方法来实现上面的效果(即对象合并),但是展开符让代码更简洁易懂。
我们来看另一个例子:
const obj1 = { a: 1, b: { c: 2 } }; const obj2 = { ...obj1 }; obj2.b.c = 3; console.log(obj1.b.c); // 3
你可能会感到惊讶:为什么在修改 obj2.b.c
的时候,obj1.b.c
也被修改了呢?这是因为对象展开符实现的是浅拷贝。也就是说,展开符只是把对象的属性一个一个地提取出来,如果这些属性是对象,那么只拷贝了其引用,没有拷贝对象本身。
理解这个细节是非常重要的,因为它可以帮助我们避免一些潜在的错误。如果需要深拷贝一个对象,可以使用第三方库 lodash
的 cloneDeep()
方法,或者手写递归实现深拷贝。
在 React 中使用对象展开符
在 React 中使用对象展开符是一个很流行的技巧,因为它可以帮助我们简化组件的代码和提高可读性。不过在这里我只介绍一个简单的应用情况。
有时候,我们需要向组件传递大量的属性,如果逐个地写出来,代码看起来就很冗长。使用展开符可以把所有属性都打包到一个对象中,然后传递给组件的 props。这个例子演示了如何实现:
const WrappedComponent = (props) => { const { a, b, c, d, e, ...others } = props; return <div>{/* 组件的实现 */}</div>; }; const App = () => { return <WrappedComponent a="1" b="2" c="3" d="4" e="5" f="6" g="7" h="8" i="9" />; };
在组件中,我们可以使用对象解构语法 { a, b, c }
把需要使用的属性提取出来,然后把其余的属性使用展开符号 ...others
放到一个新的对象中。由于展开符号只能用在最后,因此 others
必须放在最后面。
总结
本文介绍了 ES9 中的一个新特性:对象展开符(Object spread operator)。通过例子的演示,我们了解了展开符的基本用法和一些高级技巧。展开符不仅可以用来合并对象、扩展属性,还可以在 React 中简化代码,提高组件的可读性。希望读者可以掌握展开符的使用,学以致用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/646afe2b968c7c53b0a71a11