What is the difference between declaring an array with "array()" and "[]" in Javascript?

Asked

Viewed 18,641 times

48

6 answers

37


Both forms produce the same result (unlike String, for example, where there is difference between the literal "foo" and the object new String("foo")). In Javascript, arrays are not "special" in any way - only objects with a parameter length. Even the indices are identical to a common, texial object (ex.: arr[0] is the same as arr["0"]).

This section of the Ecmascript specification describes the literal for arrays as an "object initiator" (Object initializer), with the same effect in practice as creation new Array. Already this other section determines that a call to the constructor in function form (i.e. without the new, only Array(params)) has the same effect as its call in constructor form. So that 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 the SOEN, there are some details to consider:

  • Creating a literal array allows you to specify the initial elements as much as possible. Constructor creation allows you to specify only the length array, and nothing else (calling up the constructor with a single numerical argument). This is counterintuitive 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'
    

    Source

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

    var d = new Array(1.5); // RangeError: Invalid array length
    
  • One can redefine the builder Array as you wish (although by then it will no longer be the Array native), so as to customize the creation of new arrays. When this is done, the 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 occurs if you try to replace window.Array (i.e. modify the global object, which in the case of browsers is window), the literal creation is not affected. For these reasons, the performance of literal creation should be slightly higher, since there is no context verification in search of the variable Array, etc..

    Source

    Note: as pointed out by @bfavaretto in the comments, redefining 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 unrelated object, just with the same name, i.e. shadowing).

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

In the absence of specific information, what remains is to test and experiment (as in Reply by @Miguel Angelo, where he confirms that the prototypes are equal; the same can be observed using Object.getPrototypeOf in the two arrays and comparing them). However, in this case the specification is clear, I believe that there will be no "surprise"...

  • 2

    +1, I was to complete my response with this reset constructor case Array. It really makes a difference - and it is worth remembering that it is a bad practice.

  • 1

    @bfavaretto is right, I added a note on that. Personally, it would never occur to me to do such a thing (at most, I would redefine window.Array if I had an extreme need - although it doesn’t even affect literals...), I just "got the idea" from the answers on SOEN. I don’t want anyone to get the wrong idea out of my answer :P

14

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

For example, if you pass any value that is not numeric integer, you will be 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 it is an integer numeric value, you are creating an array with length (property length) equal to past value:

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

Note that actually the array nay is filled with undefined; the output we see on the console is a consequence of how the method works toString of it. It is possible to demonstrate this, for example by executing b.hasOwnProperty("0"), whose result is false.


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


Note 2: if the manufacturer Array is redefined, arrays created with the literal form [] are not affected. And arrays created with the "false" constructor will not be true arrays.

4

The difference should be minimal (i.e. only in the code as far as I can see). I had the idea to test with the prototype of the Array, before instantiating either using the literal form, or using the constructor with the operator new... the additional property I put in the prototype ended up in both instances:

Array.prototype.myVar = 10928;

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

alert("a.myVar = " + a.myVar + "; b.myVar = " + b.myVar );

0

I believe that the only difference is the mode of declaration, the var matriz will be understood as being a Array or not, at least semantically.

0

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

0

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

It is identical the construction of a function that can be made both 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.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.