原文链接 http://thecodebarbarian.com/object-assign-vs-object-spread.html
在 2018 年 Object Rest/Spread Proposal 达到了 stage 4,这意味着在未来它会将入到 ECMAScript 标准中。它也被加入到Node LTS. Node.js 8 以后的版本你可以使用它,所以你可以放心地开始使用它。
Object Spread 也可以叫做对象展开符,下文都以 Object Spread 来进行描述。
Object Spread 和 Object.assign 在功能上很相似。你应该使用哪一个? 事实证明,答案比你想象的要微妙许多。
Object Spread 概论
Object Spread 运算符的基本思想是使用现有对象的自身属性来创建新的普通对象。 所以 {...obj}
创建一个和 obj
具有相同属性的对象。 对于普通的旧 JavaScript 对象,你实际上是在创建一个 obj
副本。
与object .assign()类似,Object spread 操作符不复制继承的属性或类的属性。但是它会复制 ES6 的 symbols 属性。
还可以使用 Object spread 操作符混合其他属性。
顺序问题: Object spread 操作符将覆盖在它之前定义的属性。
和 Object.assign() 的区别
对于上面的例子, Object.assign()
函数基本上可以与 Object spread 操作符互换。事实上,object spread spec 明确指出 {...obj}
等同于 Object.assign({},obj)
。
那么你为什么要使用其中一个呢?一个关键的区别是 Object spread 操作符总是给你一个POJO(Plain Ordinary JavaScript Object)。而 Object.assign()
函数却修改其第一个传入对象 obj
:
换句话说,Object.assign()
修改了一个对象,因此它可以触发 ES6 setter。如果你更喜欢使用immutable技术,那么 Object spread 操作符就是你更好的选择。使用 Object.assign()
,你必须确保始终将空对象 {}
作为第一个参数传递。
性能怎么样? 这是一些简单的基准测试。如果将空对象作为第一个参数传递给 Object.assign()
,看起来 Object spread 会更快,但除此之外它们是可互换的。
下面是一个使用 Object.assign()
和in-place赋值的基准测试:
在这种情况下,两者是相似的:
但是,一旦向 Object.assign()
输入一个空对象参数,对象扩展运算符就会更快
这是输出:
ESLint 配置
默认情况下,ESLint在解析层面禁止对象rest / spread运算符你需要在.eslintrc.yml中将parserOptions.ecmaVersion选项设置为至少9,否则你将得到一个解析错误。
ESLint添加了一个新的规则prefer-object-spread,它会强制你使用 Object spread 操作符 而不是 Object.assign()
。 要启用此规则,请使用:
现在,如果您使用 object.assign()
而不是Object spread, ESLint将报告一个错误。
最后
Object rest / spread运算符在语法更加简洁,并且比 Object.assign()
提供了性能优势。 如果你运行的是Node.js 8或更高版本,请尝试使用这些新运算符,使代码更简洁。