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

IT技术 javascript ecmascript-6 spread-syntax
2021-02-24 16:37:12

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

console.log({...undefined})

为什么在数组中传播 undefined 会给你一个错误? [...undefined] // type error

console.log([...undefined])

2个回答

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

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

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

分配功能用于所有从一个或多个源对象可枚举自己的属性的值复制到目标对象。分配函数被调用时,都采取了以下措施:

  1. 让成为ToObject(目标)。
  2. ReturnIfAbrupt(到)。
  3. 如果只传递了一个参数,则返回。
  4. 让 source 是从第二个参数开始的参数值列表
  5. 对于源的每个元素 nextSource,按索引升序,执行
    1. 如果 nextSource 为undefinednull,则让 keys 为空List
    2. 别的, ...

...接着是复制自己的属性的描述。Object Rest/Spread Properties 的草案在这里它不是 Ecma-262 6.0 的一部分。

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

SpreadElement : ... 赋值表达式

  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 || []) ];

1setter 的处理方式有所不同

通常,使用 of...x需要x可迭代的,因为...通常的目的是将可迭代对象扁平化为其组件。

但是,{...x} 需要x可枚举的,因为我们不仅需要值,还需要键。

null不可迭代它没有组件,因此迭代 没有意义nullfor (const item of null)同样会失败。)

然而,null可枚举的null有时被视为对象,这是其中一种情况,并且对象是可枚举的,因为它们可以具有属性。for (const prop in null)同样会成功。)