Object spread 语法从不抛出错误吗?

Does the Object spread syntax never throw an error?

我注意到 Object Spread 语法对它可以接受的值类型非常宽松:

console.log({ ...true });
console.log({ ...false });
console.log({ ...0 });
console.log({ ...42 });
console.log({ ...-1 });
console.log({ ...NaN });
console.log({ ...'batman' });
console.log({ .../\w+[0-9a-fA-F]?/ });
console.log({ ...['foo', 'bar', 42] });
console.log({ ...undefined });
console.log({ ...false });
console.log({ ...Symbol('hmm') });
console.log({ ...Promise.resolve('resolved') });
console.log({ ...Promise.reject('rejected') });

是否有类型、class 或值在对象字面量中传播时无效(即抛出任何类型的错误)?当然,不包括未兑现的拒绝承诺。

不,在对象字面量中传播时没有无效的表达式,当然前提是对该表达式本身的求值不会引发错误。

从ECMAScript规范中我们可以看出是这样的:

12.2.6 Object Initializer处,我们找到对象字面量展开语法的语法定义:

PropertyDefinition:
... AssignmentExpression[+In, ?Yield, ?Await]

一个 AssignmentExpression 表示所有可能的表达式(包括赋值),逗号运算符除外,这实际上意味着如果您希望将逗号解释为,则需要使用括号逗号运算符而不是对象文字的逗号分隔符(参见 12.15 Assignment Operators and 12.16 Comma Operator)。

评估程序在12.2.6.8 Runtime Semantics: PropertyDefinitionEvaluation中指定:

PropertyDefinition:...AssignmentExpression

  1. Let exprValue be the result of evaluating AssignmentExpression.
  2. Let fromValue be ? GetValue(exprValue).
  3. Let excludedNames be a new empty List.
  4. Return ? CopyDataProperties(object, fromValue, excludedNames).

我们假定表达式本身不会在求值过程中抛出异常,这意味着上述 GetValue 过程将成功无错。然后我们可以检查 CopyDataProperties 在 7.3.25 CopyDataProperties 中做了什么。重要的步骤是:

  1. If source is undefined or null, return target.
  2. Let from be ! ToObject(source).

现在,当 sourcenullundefined 时,ToObject 会抛出异常,但这两种情况已经在上一步。所有其他原始值都装箱到包装器对象中(参见 7.1.18 ToObject)。

最后,CopyDataProperties 还有一个可能抛出的步骤:

  1. c. 2. ii. Perform ! CreateDataPropertyOrThrow(target, nextKey, propValue).

但是只有当要设置的 属性 已经存在且不可配置,或者目标对象不可扩展时才会抛出(参见 7.3.7 CreateDataPropertyOrThrow and 7.3.5 CreateDataProperty)。但是这种情况不会出现在对象字面量中。它们可能发生在扩展对象的较大评估中,但此类错误与扩展语法无关特别是.