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
325 views
in Technique[技术] by (71.8m points)

javascript - What does [undefined × 2] mean and why is it different to [undefined,undefined]?

While answering this question ( Difference between [Object, Object] and Array(2) ) I happened across something in JavaScript arrays that I wasn't previously aware of (ironic, considering I worked on Arrays in the Chakra engine while at Microsoft).

If I enter this into Chrome's JavaScript console...

var x = Array(2);
var y = [undefined, undefined];
var z = [,];

...then when query the x, y and z variables I get this output respectively:

> x
< [undefined × 2]
<    length: 2

> y
< [undefined, undefined] (
<    0: undefined
<    1: undefined
<    length: 2

> z
< [undefined × 1]
<    length: 1

MDN's relevant documentation for Array(arrayLength) and the [] literal syntax states:

If the only argument passed to the Array constructor is an integer this returns a new JavaScript array with its length property set to that number (Note: this implies an array of arrayLength empty slots, not slots with actual undefined values). If the argument is any other number, a RangeError exception is thrown.

I note that the documentation does not further explicate on the concept of a "slot" - I assume they're using it as a synonym for "array element" (I'm aware that JavaScript arrays can be sparse-arrays that have a different internal representation, but that shouldn't affect how consumers see them - given that JavaScript arrays and objects are abstractions over a variety of data structures anyway).

The documentation on MSDN for the same does not provide any mention of edge-case arguments for the Array function or Array-literal [] syntax.

So my questions are:

  • What does undefined × 2 mean?
  • Why does Array(2) evaluate to [undefined × 2] instead of [undefined, undefined]?
  • Why does [,] have a length: 1?

To attempt to answer my own questions I consulted the ECMA-262 7.0 specification on Array Literals. There's an interesting note on elided array literal elements (emphasis mine):

Array elements may be elided at the beginning, middle or end of the element list. Whenever a comma in the element list is not preceded by an AssignmentExpression (i.e., a comma at the beginning or after another comma), the missing array element contributes to the length of the Array and increases the index of subsequent elements. Elided array elements are not defined. If an element is elided at the end of an array, that element does not contribute to the length of the Array.

So the part in bold answers my third question, at least: if the last element is "missing" then it does not exist, and if a non-terminal element doesn't have a value then it's undefined. So these expressions are equivalent:

[a,]   --> [a]
[a,b,] --> [a,b]
[a,,b] --> [a,undefined,b]

Therefore

[,]    --> [undefined]
[,,]   --> [undefined,undefined]

So I tried this in Chrome:

> var a = [,,];
> a
> [undefined × 2]
>    length: 2

This is unexpected! I thought [,,] to be equivalent to [undefined,undefined] as per the explicit rules of element elision, yet Chrome considers [,,] to be equivalent to Array(2) instead (note there are no indexers defined, giving it the same result as case y).

So my forth question:

  • Why is [,,] equivalent to Array(2) but not [undefined,undefined]?
See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

What does undefined × 2 mean?

Consoles display what some developer has decided is a useful message based on some input. It should not be regarded as normative in any sense, and in some cases is misleading. The statement:

var x = Array(2);

Creates a variable x and assigns a new array with length 2. There are no "empty slots" in any meaningful sense. It is equivalent to:

var x = [,,];

(noting that old IE had a bug where the above created an array with length 3 not 2). You can think of it as an object like:

var x = {length: 2};

The number of properties that can be added is in no way limited by setting the length. However setting the length of an existing array will delete any members with indexes equal to or higher than the new length.

Having said that, implementations are free to allocate space for "length" worth of indexes, which seems to be a performance boost in some cases, but it's not specified as being required by ECMA-262.

Why does Array(2) evaluate to [undefined × 2] instead of [undefined, undefined]?

See above, the console is just trying to be helpful. There are no undefined members at all, there is just an array with length 2. For the record, IE 10 shows:

[undefined, undefined]

which is also misleading for the above reasons. It should show [,,].

Why does [,] have a length: 1?

That is called an elision, which is part of an array initializer or array literal. It creates a "missing" member in the same way that:

var x = [];
x[0] = 0;
x[2] = 2;

does not have a member at index 1 and is equivalent to:

var x = [0,,2];

Noting again that old IE interpreted [,] as having length of 2. The member at index 1 is said to be "elided".


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

...