对象传播语法永远不会抛出错误吗?

Phi*_*ang 5 javascript spread-syntax ecmascript-2018

我注意到 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') });
Run Code Online (Sandbox Code Playgroud)

在对象字面量中传播时,是否存在无效的类型、类或值(即引发任何类型的错误)?当然,不包括未捕获的拒绝承诺。

tri*_*cot 3

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

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

12.2.6 对象初始化器中,我们找到了对象字面量扩展语法的语法定义:

PropertyDefinition :
... 赋值表达式[+In, ?Yield, ?Await]

赋值表达式表示所有可能的表达式(包括赋值),除了逗号运算符,这实际上意味着如果您希望将逗号解释为逗号运算符而不是对象字面量的逗号分隔符,则需要使用括号(请参阅 12.15 赋值运算12.16 逗号运算符)。

评估过程在12.2.6.8 运行时语义:PropertyDefinitionEvaluation中指定:

属性定义...赋值表达式

  1. exprValue为计算AssignmentExpression的结果。
  2. fromValue为 ? 获取值(表达式值)。
  3. exceptedNames成为一个新的空列表。
  4. 返回 ?CopyDataProperties(对象fromValueexclusionNames)。

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

  1. 如果undefinedor null,则返回目标
  2. 让我们成为吧!ToObject().

现在,当sourcenull或 时, ToObject 会抛出undefined异常,但这两种情况已在上一步中被处理(作为无操作)。所有其他原始值都装箱到包装对象中(请参阅7.1.18 ToObject)。

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

  1. C。2. 二. 履行 !CreateDataPropertyOrThrow(目标, nextKey , propValue )。

但只有当要设置的属性已存在且不可配置,或者目标对象不可扩展时才会抛出(请参见7.3.7 CreateDataPropertyOrThrow7.3.5 CreateDataProperty)。但这样的情况不会出现在对象字面量中。它们可能发生在扩展对象的较大计算中,但此类错误与扩展语法无关