17

I was just fiddling with some JS and found something I thought would not happen.

var arr = [,];
arr.length // 1
arr[0] // undefined

Moreover, [,,] has a length of 2. Shouldn't these arrays have lengths of 0? I thought commas were only used to separate elements in an array, so why does it appear that commas are counted as elements in these particular arrays? Does this kind of behavior with arrays have any sort of application?

sdfsdf
  • 5,052
  • 9
  • 42
  • 75
  • 7
    possible duplicate of [What is the difference between `[undefined]` and `[,]`?](http://stackoverflow.com/q/11808946/1048572) – Bergi Apr 01 '16 at 04:14
  • 1
    …and also related: [Length of Array Differs In Internet Explorer With Trailing Comma](http://stackoverflow.com/q/6541163/1048572) – Bergi Apr 01 '16 at 04:17
  • 1
    @Gothdo: Because I wasn't sure whether it's an exact duplicate ("explain the difference" vs "why do they have a length"), because that is not explained that well, because I've answered the duplicate, because the proposed duplicate is closed as a duplicate itself… Too much doubt to hammer it instantly. Given that quite a lot of people seem to agree, I'll do now. – Bergi Apr 05 '16 at 21:49

3 Answers3

45

In an array literal, a comma at the end is ignored, but all the other commas delimit elements. If you omit the value of an element, it defaults to undefined, but the element is still there. So

[,]

is equivalent to

[undefined,]

which is equivalent to

[undefined]

This has 1 element whose value is undefined.

Similarly

[,,] = [undefined, undefined, ] = [undefined, undefined]

which has 2 elements.

The default element behavior is more useful when you want to omit elements in the middle of an array.

[1, 2, 3, , , 6, 7, 8]

Actually, there's a small difference between the two ways of creating undefined elements. In Javascript, an array is actually an object that has a length property and properties whose names are the indexes of the array elements. Normally, if an array has length = N, the index properties will be all the integers from 0 to N-1. But when you omit an element in the array literal, no property is created for that index.

For most purposes, this missing property is not significant, because accessing a nonexistent property of an object returns undefined, just as if you have a property whose value is undefined. You can only detect these missing properties by using a method like hasOwnProperty or calling Object.keys. The Javascript console uses something like this to display gaps in the array differently from explicit undefined elements.

So

Object.getOwnPropertyNames([1, 2, 3]) => ["0", "1", "2", "length"]
Object.getOwnPropertyNames([1, , 3, 4]) => ["0", "2", "3", "length"]
Object.getOwnPropertyNames([, , , , ]) => ["length"]

The reason for ignoring the last comma is so you can write:

[ 
    "foo",
    "bar",
    "baz",
    "quux",
]

This makes editing easier, because you can insert and delete lines without having to special-case the last element.

Barmar
  • 741,623
  • 53
  • 500
  • 612
8

That's called elision. It creates a "hole" in the array (a sparse array). There are probably applications I don't know about and have forgotten about, the only one I can think of right now is the one I show here: https://stackoverflow.com/a/29629588/1034448.

[,...Array(10)].map((x, i) => { /* range of `i` is 1 - 10 */ })

[,,] is not equivalent to [undefined, undefined,]. There is a big difference: iteration methods will not include elements at the elided indexes. Example:

var enumerated = [];

function callback (x, i) {
  enumerated.push(i);
}

[,,].forEach(callback);
console.log(enumerated); // logs []

[undefined, undefined,].forEach(callback);
console.log(enumerated); // logs [1, 2]
Community
  • 1
  • 1
JMM
  • 26,019
  • 3
  • 50
  • 55
3

Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Array_literals

The trailing comma is ignored in newer browsers.

xiaoyi
  • 6,641
  • 1
  • 34
  • 51