ES6 扩展运算符在对象上的应用是标准的 ECMAScript 规范吗?

Is application of the ES6 spread operator on Objects a standard ECMAScript specification?

本文关键字:ECMAScript 标准 范吗 应用 运算符 对象 ES6 扩展      更新时间:2023-09-26

MDN 将扩展运算符的用法定义为仅用于数组。

例如,点差运算符的正确用法如下所示

var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes']; // ["head", "shoulders", "knees", "and", "toes"]

我们在数组parts上应用了扩展运算符。

但是在 React 文档中,他们在这样的对象上使用 spread 运算符

var props = {}; 
props.foo = x; 
props.bar = y; 
var component = <Component {...props} />;

如果我实际上尝试在控制台中执行此操作,则会收到类型错误

var a = {b:1,c:2}
console.log(...a);  // TypeError

我的问题是:

  • 在对象上使用 spread 运算符是否是规范中实现的标准(并且此用例不知何故从 MDN 文档中省略了,我试图展示的控制台示例没有正确完成,因此给出了 TypeError)?
  • 如果不是标准实现,那么在幕后发生了什么,允许 React 组件巧妙地使传播运算符以它所做的非标准方法(即作用于对象)进行操作,并抑制这样做时不可避免地出现的 TypeError?

如果我实际上尝试在控制台中执行此操作,则会收到类型错误

在这里混淆了一些东西(如果它们看起来都相似,不能责怪你)。

在您的示例中,

console.log(...a);

...a不是对象传播的应用。它有时被称为传播语法(即使这个语法特别没有真正的名称),这在 ES2015 中是标准化的。它在函数调用中用作最后一个"参数",并且仅适用于可迭代对象。对象不是可迭代对象,因此会出现错误。

对象

传播(当前是一个提案)仅用于对象文字

var foo = {x: 42};
var bar = {y: 21, ...foo}; // equivalent to Object.assign({y: 21}, foo);

引擎盖下

发生了什么

JSX(<Component {...props} />)内部的使用又是略有不同的,它是一个JSXSpreadAttribute,但它确实对对象传播进行了脱糖。如果你在 Babel 中尝试一下,你可以看到它被转换成了什么:

var _extends = Object.assign || /* polyfill */;
React.createElement(Component, _extends({ foo: true }, props));

点差运算符目前正在标准化,因此不能仅与 ES2015 一起使用。目前,这是该过程第二阶段的提案,并且可能位于ES2017规范中。

https://github.com/sebmarkbage/ecmascript-rest-spread

转译到 ES5 时,已经可以通过使用一些额外的 babel 插件来利用它。这就是您提到的示例中使用的内容。

http://babeljs.io/docs/plugins/transform-object-rest-spread/

http://babeljs.io/docs/plugins/preset-stage-2/