Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
530 views
in Technique[技术] by (71.8m points)

javascript - Spreading undefined in array vs object

Why does spreading undefined in an object return an empty object? {...undefined} // equals {}:

console.log({...undefined})
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As noted in the comments, and summarized by @ftor from #687, object spread is equivalent1 to Object.assign() (issues #687, #45), whereas spread in array literal context is iterable spread.

Quoting Ecma-262 6.0, Object.assign() is defined as:

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:

  1. Let to be ToObject(target).
  2. ReturnIfAbrupt(to).
  3. If only one argument was passed, return to.
  4. Let sources be the List of argument values starting with the second argument.
  5. For each element nextSource of sources, in ascending index order, do
    1. If nextSource is undefined or null, let keys be an empty List.
    2. Else, ...

...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 in an array literal expression is defined to begin as follows:

SpreadElement : ... AssignmentExpression

  1. Let spreadRef be the result of evaluating AssignmentExpression.
  2. Let spreadObj be GetValue(spreadRef).
  3. Let iterator be GetIterator(spreadObj).
  4. ReturnIfAbrupt(iterator).

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: There is a difference in how setters are handled.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...