在数组与对象中传播未定义

0xt*_*mur 24 javascript ecmascript-6 spread-syntax

为什么在对象中传播undefined会返回一个空对象?{...undefined} // equals {}:

console.log({...undefined})
Run Code Online (Sandbox Code Playgroud)

为什么在数组中传播未定义会给出错误? [...undefined] // type error:

console.log([...undefined])
Run Code Online (Sandbox Code Playgroud)

Ilj*_*ilä 30

正如在评论中所指出,并从由@ftor总结#687,对象传播相当于1Object.assign() (问题#687,#45),其中,如在传播数组文本上下文是可迭代传播.

引用Ecma-262 6.0,Object.assign()定义为:

19.1.2.1 Object.assign(target,... sources)

分配功能用于所有从一个或多个源对象可枚举自己的属性的值复制到目标对象.调用assign函数时,执行以下步骤:

  1. 让我们成为ToObject(目标).
  2. ReturnIfAbrupt(to).
  3. 如果只传递了一个参数,则返回.
  4. 让sources成为以第二个参数开头的参数列表.
  5. 对于每个元素nextSource of sources,按升序索引顺序执行
    1. 如果nextSource 未定义或为null,则让键为空List.
    2. 否则,......

...后面是复制自己的属性的描述.对象休息/传播属性草案在这里.它不是Ecma-262 6.0的一部分.

SpreadElement在数组文本表达被定义为开始如下:

SpreadElement:... AssignmentExpression

  1. spreadRef是评估AssignmentExpression的结果.
  2. spreadObjGetValue(spreadRef).
  3. 迭代器成为GetIterator(spreadObj).
  4. ReturnIfAbrupt(迭代器).

而且,由于undefined不具有属性与关键@@迭代器,一个类型错误被抛出,基于步骤GetIterator.标准不是一个简单的读取,但如果我没有弄错,错误的路径是GetIterator - > GetMethod - > GetV - > ToObject,它会为undefined和null抛出TypeError.

在数组初始化中使用可能未定义值的变量的一个简单方法是使用默认值:

const maybeArray = undefined;
const newArray = [ ...(maybeArray || []) ];
Run Code Online (Sandbox Code Playgroud)

1:处理器的处理方式有所不同.


ike*_*ami 17

通常, 的使用...x要求x是可迭代的,因为 的目的...通常是将可迭代对象扁平化为其组件。数组是可迭代的一个主要例子。

undefined是不可迭代的。它没有组件,因此迭代 没有意义undefined[...undefined]因此失败了。for (const e of undefined)同样失败,因为of也需要一个iterable

然而,{...x} 要求x是可枚举的,因为它不仅需要值,还需要键。对象是可枚举的一个主要示例。

undefined可枚举的undefined有时被视为一个对象,这就是其中一种情况。对象是可枚举的,因为它们可以具有属性。{...undefined}因此成功了。for (const p in undefined)同样成功,因为in需要一个可枚举的.


关于的注释null

询问 的null作为操作数的行为的问题...作为该问题的重复项被关闭。虽然nullundefined具有不同的类型,但上述答案同样适用于null