在数组与对象中传播未定义 [英] Spreading undefined in array vs object
问题描述
为什么在对象中传播undefined会返回一个空对象? {... undefined} // equals {}
:
Why does spreading undefined in an object return an empty object? {...undefined} // equals {}
:
console.log({...undefined})
为什么在数组中传播undefined会给你一个错误?
[... undefined] //输入错误
:
And Why does spreading undefined in an array give you an error?
[...undefined] // type error
:
console.log([...undefined])
推荐答案
如评论中所述,并由@ftor从#687 ,对象传播相当于 1 到 Object.assign()(问题#687 ,#45 ),数组文字上下文中的差异是可迭代的。
As noted in the comments, and summarized by @ftor from #687, object spread is equivalent1 to Object.assign() (issues #687, #45), where as spread in array literal context is iterable spread.
引用 Ecma-262 6.0 , Object.assign()定义为:
19.1.2.1 Object.assign(target,... sources)
assign 函数用于复制值从一个或多个源对象到目标对象的所有可枚举的自有属性。调用 assign 函数时,将执行以下步骤:
19.1.2.1 Object.assign ( target, ...sources )
The assign function is used to copy the values of all of the enumerable own properties from one or more source objects to a target object. When the assign function is called, the following steps are taken:
- 设为 ToObject (目标)。
- ReturnIfAbrupt (至)。
- 如果只传递了一个参数,请返回。
- 让来源为列表以第二个参数开头的参数值。
- 对于每个元素nextSource of sources,按升序索引顺序,执行
- Let to be ToObject(target).
- ReturnIfAbrupt(to).
- If only one argument was passed, return to.
- Let sources be the List of argument values starting with the second argument.
- For each element nextSource of sources, in ascending index order, do
- 如果nextSource 未定义或 null ,让密钥为空列表。
- 其他,...
- If nextSource is undefined or null, let keys be an empty List.
- Else, ...
...后面跟着复制自己的属性的描述。对象休息/传播属性草案是此处。它不是Ecma-262 6.0的一部分。
...followed by the description of copying own properties. The draft of Object Rest/Spread Properties is here. It is not a part of the Ecma-262 6.0.
A SpreadElement 定义为如下所示:
A SpreadElement in an array literal expression is defined to begin as follows:
SpreadElement : ... AssignmentExpression
- 让 spreadRef 成为评估 AssignmentExpression 的结果。
- 让 spreadObj GetValue ( spreadRef )。
- 让 iterator 成为 GetIterator ( spreadObj )。
- < a href =https://www.ecma-international.org/ecma-262/6.0/index.html#sec-returnifabrupt\"rel =nofo llow noreferrer> ReturnIfAbrupt (迭代器)。
- Let spreadRef be the result of evaluating AssignmentExpression.
- Let spreadObj be GetValue(spreadRef).
- Let iterator be GetIterator(spreadObj).
- ReturnIfAbrupt(iterator).
并且因为 undefined
没有带密钥的属性 @@ iterator ,基于 TypeError 6.0 / index.html#sec-getiteratorrel =nofollow noreferrer> GetIterator 。标准不是一个简单的阅读,但如果我没有弄错,错误的途径是 GetIterator - > GetMethod - > GetV - > ToObject ,这会为undefined和null抛出TypeError。
And since undefined
does not have a property with the key @@iterator, a TypeError is thrown, based on the steps of GetIterator. The standard is not an easy read, but if I'm not mistaken, the path to error is GetIterator -> GetMethod -> GetV -> ToObject, which throws a TypeError for undefined and null.
在数组初始化中使用可能未定义的值的变量的一个简单方法是使用默认值:
A simple remedy to using variables with possibly undefined value in array initialization is to use a default:
const maybeArray = undefined;
const newArray = [ ...(maybeArray || []) ];
1 :有是如何处理设置者。
这篇关于在数组与对象中传播未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!