What's the difference between declaring an array with "array ()" and "[]" in JavaScript?

45

In JavaScript we can declare an array in two ways:

var matriz = new Array();

and

var matriz = [];

What is the difference between the two and what are their consequences?

This question is being posed for the purpose of documenting in Portuguese the original version that can be seen in SOEN: What's the difference between "Array ()" and "[]" while declaring a JavaScript array?     

asked by anonymous 04.03.2014 / 21:48

6 answers

33

Both forms produce the same result (unlike String , for example, where there is difference between the literal "foo" and the new String("foo") object). In JavaScript, arrays are not "special" in any way - just objects with a length parameter. Even the indexes are identical to that of a common textual object (eg, arr[0] is the same as arr["0"] ).

This section of the ECMAScript specification describes the literal for arrays as a "object initializer", with the same effect in practice as creation via new Array . Already this other section determines that a call to the constructor in function form ( ie without new , only Array(params) ) has the same effect as your call in builder form. So the three forms are in fact equivalent:

var arr = new Array(element0, element1, ..., elementN);
var arr = Array(element0, element1, ..., elementN);
var arr = [element0, element1, ..., elementN];

As pointed out in the answers to the similar question in SOEN, there are some details to consider:

  • Creating an array via literal allows you to specify the initial elements at most. Creation via constructor allows specifying only the length of the array, and nothing else (called the constructor with a single numeric argument). This is counter-intuitive and can cause unexpected errors:

    var a = new Array(1);   // length:1 (e mais nada)
    var b = new Array(1,2); // length:2, 0:1, 1:2
    var c = new Array('1'); // length:1, 0:'1'
    

    Font

    Note: If used this way, the number must necessarily be integer. This call for example throws an exception:

    var d = new Array(1.5); // RangeError: Invalid array length
    
  • You can reset the Array constructor however you want (even though it is no longer the Array native), in order to customize the creation of new arrays. When you do this, literal creation is not modified:

    var proto = Array.prototype;
    function Array() {
        this.is = 'SPARTA';
    }
    Array.prototype = proto;
    
    var a = new Array();
    var b = [];
    
    alert(a.is);  // => 'SPARTA'
    alert(b.is);  // => undefined
    

    The same happens if you attempt to replace window.Array (i.e. modify the global object, which in the case of browsers is window ), creation via literal is not affected. For these reasons, the creation performance via literal should be slightly larger, since there is no context checking for the variable Array , etc.

    Font

    Note: As pointed out by @bfavaretto in the comments, resetting native JavaScript objects is a bad practice (aggravated by the fact that it is not exactly a redefinition that is being done, but creating an object unrelated, just with the same name, ie shadowing ).

Although the above is in compliance with the specification, particular implementations can do optimizations in either case. As noted in that related question , sometimes two constructs that at first glance seem equivalent have radically different performance in practice. The same goes for using a Array or simply an array-like (ie a common object with a length field).

In the absence of specific information, all that remains is testing and experimenting (as in the @Miguel Angelo answer , where it confirms that prototype s is equal, it can be observed using Object.getPrototypeOf in both arrays and comparing them). However, in this case the specification is clear, I believe there will be no "surprise" ...

    
04.03.2014 / 22:31
13

In the code you used as an example, there is no difference. However, the Array constructor can receive parameters, and depending on what is passed it behaves differently.

For example, if you pass any value other than numeric integer, you are creating an array containing what was passed:

var a = new Array('um', 'dois');
console.log(a); // ["um", "dois"]

If you pass only one parameter, and if it is an integer value, you are creating an array with length (property length ) equal to the value passed:

var b = new Array(4);
console.log(b); // [undefined, undefined, undefined, undefined]

Note that in fact the array is not filled with undefined ; the output we see on the console is a consequence of how the toString method works. You can demonstrate this, for example by running b.hasOwnProperty("0") , whose result is false .

Note 1 : The Array constructor can be used with or without new , and the result will be the same.

Note 2 : If the Array constructor is redefined, arrays created with the literal form [] are not affected. And arrays created with the "fake" constructor will not be real arrays.

    
04.03.2014 / 22:28
3

The difference should be minimal (i.e. only in the code from what I can see). I had the idea of testing with prototype of the Array, before instantiating both using the literal form and using the constructor with the new operator ... the additional property that I placed in the prototype went to both instances:

Array.prototype.myVar = 10928;

var a = [];
var b = new Array();

alert("a.myVar = " + a.myVar + "; b.myVar = " + b.myVar );
    
04.03.2014 / 22:07
0

I think the only difference is the way of declaration, var matriz will be understood to be Array or not, at least semantically.

    
04.03.2014 / 22:08
0

There is no difference, both are equally accepted forms for building the Array.

It is identical to building a function that can be done either of the form:

function sum(x,y) = {
   var x = 1;
   var y = 1;
   console.log(x+y);
}

or:

var sum = new function(x,y) = {
   var x = 1;
   var y = 1;
   console.log(x+y);
}

Both return the same exact function.

    
05.03.2014 / 17:16
0

Only syntactic sugar. Using "[]" is the literal form of instantiation via the constructor function (Array).

    
18.03.2014 / 14:57