5

我注意到 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') });

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

4

1 回答 1

3

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

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

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

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

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

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

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

  1. exprValue为评估AssignmentExpression的结果。
  2. fromValue是 ? 获取值(exprValue)。
  3. excludeNames成为一个新的空列表。
  4. 返回 ?CopyDataProperties(对象fromValueexcludedNames)。

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

  1. 如果sourceundefinedor null,则返回target
  2. 是!对象()。

现在 ToObject 会在sourcenullor时抛出undefined,但这两种情况在前面的步骤中已经被处理(作为无操作)。所有其他原始值都被装箱到一个包装对象中(参见7.1.18 ToObject)。

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

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

但这只能在要设置的属性已经存在且不可配置,或者目标对象不可扩展时抛出(参见7.3.7 CreateDataPropertyOrThrow7.3.5 CreateDataProperty)。但是这样的条件不会出现在对象字面量中。它们可能发生在扩展对象的更大评估中,但此类错误与特定的扩展语法无关。

于 2021-06-20T08:43:09.987 回答