假设我有一个选项变量我想设置一个默认值。
这两种选择的优点/缺点是什么?
使用对象扩展
options = {...optionsDefault, ...options};
或者使用Object.assign
options = Object.assign({}, optionsDefault, options);
这是让我疑惑的承诺。
假设我有一个选项变量我想设置一个默认值。
这两种选择的优点/缺点是什么?
使用对象扩展
options = {...optionsDefault, ...options};
或者使用Object.assign
options = Object.assign({}, optionsDefault, options);
这是让我疑惑的承诺。
当前回答
这并不一定详尽无遗。
传播的语法
options = {...optionsDefault, ...options};
优点:
如果在没有本机支持的环境中编写代码以执行,则可以只编译此语法(而不是使用polyfill)。(比如巴别塔。) 可以减少复杂性。
缺点:
当这个答案最初被写出来的时候,这是一个建议,没有标准化。在使用提案时,请考虑如果您现在使用提案编写代码,而它没有得到标准化或在向标准化发展的过程中发生变化,该怎么办。这已经在ES2018中标准化了。 字面的,不是动态的。
Object.assign ()
options = Object.assign({}, optionsDefault, options);
优点:
标准化。 动态的。例子: var sources = [{a: " a "}, {b: " b "}, {c: " c "}]; options = Object.assign。应用(对象,({}).concat(来源)); / /或 options =对象。分配({},…来源);
缺点:
更详细的。 如果在没有本机支持的环境中编写代码执行,则需要填充。
这是让我疑惑的承诺。
这和你问的问题没有直接关系。这段代码没有使用Object.assign(),而是使用用户代码(object-assign)来做同样的事情。他们似乎在用Babel编译代码(并将其与Webpack捆绑),这就是我所说的:你可以编译的语法。他们显然更喜欢这样,而不是必须将对象赋值作为一个依赖项包含到他们的构建中。
其他回答
其他答案都老了,得不到好的答案。 下面的例子是对象字面量,有助于两者如何相互补充,以及如何不能相互补充(因此存在差异):
var obj1 = { a: 1, b: { b1: 1, b2: 'b2value', b3: 'b3value' } };
// overwrite parts of b key
var obj2 = {
b: {
...obj1.b,
b1: 2
}
};
var res2 = Object.assign({}, obj1, obj2); // b2,b3 keys still exist
document.write('res2: ', JSON.stringify (res2), '<br>');
// Output:
// res2: {"a":1,"b":{"b1":2,"b2":"b2value","b3":"b3value"}} // NOTE: b2,b3 still exists
// overwrite whole of b key
var obj3 = {
b: {
b1: 2
}
};
var res3 = Object.assign({}, obj1, obj3); // b2,b3 keys are lost
document.write('res3: ', JSON.stringify (res3), '<br>');
// Output:
// res3: {"a":1,"b":{"b1":2}} // NOTE: b2,b3 values are lost
这里还有几个小例子,同样是数组和对象: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
这并不一定详尽无遗。
传播的语法
options = {...optionsDefault, ...options};
优点:
如果在没有本机支持的环境中编写代码以执行,则可以只编译此语法(而不是使用polyfill)。(比如巴别塔。) 可以减少复杂性。
缺点:
当这个答案最初被写出来的时候,这是一个建议,没有标准化。在使用提案时,请考虑如果您现在使用提案编写代码,而它没有得到标准化或在向标准化发展的过程中发生变化,该怎么办。这已经在ES2018中标准化了。 字面的,不是动态的。
Object.assign ()
options = Object.assign({}, optionsDefault, options);
优点:
标准化。 动态的。例子: var sources = [{a: " a "}, {b: " b "}, {c: " c "}]; options = Object.assign。应用(对象,({}).concat(来源)); / /或 options =对象。分配({},…来源);
缺点:
更详细的。 如果在没有本机支持的环境中编写代码执行,则需要填充。
这是让我疑惑的承诺。
这和你问的问题没有直接关系。这段代码没有使用Object.assign(),而是使用用户代码(object-assign)来做同样的事情。他们似乎在用Babel编译代码(并将其与Webpack捆绑),这就是我所说的:你可以编译的语法。他们显然更喜欢这样,而不是必须将对象赋值作为一个依赖项包含到他们的构建中。
对象扩展操作符(…)在浏览器中不起作用,因为它还不是任何ES规范的一部分,只是一个建议。唯一的选择是用Babel(或类似的东西)编译它。
正如您所看到的,它只是Object.assign({})上的语法糖。
在我看来,这些是重要的区别。
对象。赋值在大多数浏览器中都有效(不需要编译) ... For对象不是标准化的 ... 防止您意外地改变对象 ... 将填充对象。在没有它的浏览器中赋值 ... 需要更少的代码来表达相同的思想
我们将创建一个名为identity的函数,它只返回我们给它的任何参数。
identity = (arg) => arg
和一个简单的数组。
arr = [1, 2, 3]
如果用arr求恒等函数,我们知道会发生什么
这现在是ES6的一部分,因此是标准化的,并且在MDN上也有文档: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
它使用起来非常方便,与对象解构一起使用也很有意义。
上面列出的另一个优势是object. assign()的动态功能,不过这就像在文字对象中展开数组一样简单。在编译后的babel输出中,它完全使用了Object.assign()所演示的内容
因此,正确的答案是使用object spread,因为它现在是标准化的,被广泛使用(参见react, redux等),易于使用,并且具有object .assign()的所有特性。