Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Array(5) equivalent to var a = []; a.length = 5; in JS?

I see four five options to initialize an array to a specific length in JS, (the last one is a stretch, I know):

var a = []; a.length = 5;

var a = Array(5);

var a = []; a[4] = undefined;

var a = new Array(5);

function makeArrayToLength(length, default){
    var a = [], i = 0;
    for(; i < length; i++){
        a[i] = default;
    }
    return a;
}

I definitely want to (and do) use the literal whenever possible, but I'm in a situation where the defining aspect of a particular array is its length, so I'm leaning towards Array(5). Is the first example equivalent to the second in terms of end result? I realize it's not equivalent in the execution.

like image 605
Andrew Avatar asked Dec 09 '10 06:12

Andrew


2 Answers

The first two, and the third examples are equivalent, at the end they produce an Array object with only one own property, length, containing 5 as its value.

When you call the Array constructor using a single numeric argument (like Array(5);), the newly created object will contain that number as its length property, the index properties aren't created:

var a = Array(5);
a.hasOwnProperty('0'); // false

The second example produces just the same:

var a = [];
a.length = 5;
a.hasOwnProperty('0'); // false

About the third example, it isn't equivalent because it will create a property on the array object, even though its value is undefined:

var a = []; a[4] = undefined;
a.hasOwnProperty('4'); // true

The fourth example:

var a = new Array(5);

Is just exactly the same as the second one (var a = Array(5);), there's no difference between using the Array constructor with or without the new operator, in the second example you are calling the Array constructor as a function.

And finally, about your makeArrayToLength function, by now I think you know isn't equivalent at all, since all the "index properties" are initialized to a "default" value. (BTW don't use default as Identifier, it's a Keyword...)

The Array constructor is usually avoided because it can have different behaviors depending the argument used, for example:

Array("5"); // one element array, (["5"])
Array(5);   // empty array, length = 5
// v.s.
["5"]       // one element array
[5]         // one element array

Also, the Array constructor could be overriden, while array literals will always work.

like image 128
Christian C. Salvadó Avatar answered Oct 20 '22 10:10

Christian C. Salvadó


Yes, they all produce the same result.

2 and 4 are the same because, according to the ECMAScript spec:

15.4.1 The Array Constructor Called as a Function When Array is called as a function rather than as a constructor, it creates and initialises a new Array object. Thus the function call Array(...) is equivalent to the object creation expression new Array(...) with the same arguments.

1 and 2 are equivalent because [] constructs a new array and setting the length property is equivalent to constructing an Array with new Array(length) (in the spec).

Option 3 is also equivalent because:

...whenever a property is added whose name is an array index, the length property is changed, if necessary, to be one more than the numeric value of that array index

And option 5 is basically just option 3, but repeated multiple times up to the maximum index.

like image 25
Hamish Avatar answered Oct 20 '22 09:10

Hamish