为什么在对象中传播 undefined 会返回一个空对象?{...undefined} // equals {}
:
console.log({...undefined})
为什么在数组中传播 undefined 会给你一个错误?
[...undefined] // type error
:
console.log([...undefined])
为什么在对象中传播 undefined 会返回一个空对象?{...undefined} // equals {}
:
console.log({...undefined})
为什么在数组中传播 undefined 会给你一个错误?
[...undefined] // type error
:
console.log([...undefined])
正如评论中所指出的,并由@ftor 从#687总结,对象传播相当于1到Object.assign()(问题#687,#45),而数组文字上下文中的传播是可迭代传播。
引用Ecma-262 6.0,Object.assign()定义为:
19.1.2.1 Object.assign ( target, ...sources )
的分配功能用于所有从一个或多个源对象可枚举自己的属性的值复制到目标对象。当分配函数被调用时,都采取了以下措施:
- 让成为ToObject(目标)。
- ReturnIfAbrupt(到)。
- 如果只传递了一个参数,则返回。
- 让 source 是从第二个参数开始的参数值列表。
- 对于源的每个元素 nextSource,按索引升序,执行
- 如果 nextSource 为undefined或null,则让 keys 为空List。
- 别的, ...
...接着是复制自己的属性的描述。Object Rest/Spread Properties 的草案在这里。它不是 Ecma-262 6.0 的一部分。
甲SpreadElement在数组文本表达被定义为开始如下:
SpreadElement : ... 赋值表达式
- 令spreadRef是对AssignmentExpression求值的结果。
- 让spreadObj为GetValue ( spreadRef )。
- 让迭代器成为GetIterator ( spreadObj )。
- ReturnIfAbrupt(迭代器)。
而且,由于undefined
没有与关键属性@@迭代器,一个类型错误被抛出,基于步骤GetIterator。该标准不容易阅读,但如果我没记错的话,错误的路径是GetIterator -> GetMethod -> GetV -> ToObject,它会为 undefined 和 null 抛出 TypeError 。
在数组初始化中使用可能具有未定义值的变量的一个简单补救方法是使用默认值:
const maybeArray = undefined;
const newArray = [ ...(maybeArray || []) ];
1:setter 的处理方式有所不同。
通常,使用 of...x
需要x
是可迭代的,因为...
通常的目的是将可迭代对象扁平化为其组件。
但是,{...x}
需要x
是可枚举的,因为我们不仅需要值,还需要键。
null
不可迭代。它没有组件,因此迭代 没有意义null
。(for (const item of null)
同样会失败。)
然而,null
是可枚举的。null
有时被视为对象,这是其中一种情况,并且对象是可枚举的,因为它们可以具有属性。(for (const prop in null)
同样会成功。)