Javascript array declaration: new Array(), new Array(3), ['a', 'b', 'c'] create arrays that behave differently

203,811

Solution 1

Arrays have numerical indexes. So,

a = new Array();
a['a1']='foo';
a['a2']='bar';

and

b = new Array(2);
b['b1']='foo';
b['b2']='bar';

are not adding elements to the array, but adding .a1 and .a2 properties to the a object (arrays are objects too). As further evidence, if you did this:

a = new Array();
a['a1']='foo';
a['a2']='bar';
console.log(a.length);   // outputs zero because there are no items in the array

Your third option:

c=['c1','c2','c3'];

is assigning the variable c an array with three elements. Those three elements can be accessed as: c[0], c[1] and c[2]. In other words, c[0] === 'c1' and c.length === 3.

Javascript does not use its array functionality for what other languages call associative arrays where you can use any type of key in the array. You can implement most of the functionality of an associative array by just using an object in javascript where each item is just a property like this.

a = {};
a['a1']='foo';
a['a2']='bar';

It is generally a mistake to use an array for this purpose as it just confuses people reading your code and leads to false assumptions about how the code works.

Solution 2

Arrays in JS have two types of properties:

Regular elements and associative properties (which are nothing but objects)

When you define a = new Array(), you are defining an empty array. Note that there are no associative objects yet

When you define b = new Array(2), you are defining an array with two undefined locations.

In both your examples of 'a' and 'b', you are adding associative properties i.e. objects to these arrays.

console.log (a) or console.log(b) prints the array elements i.e. [] and [undefined, undefined] respectively. But since a1/a2 and b1/b2 are associative objects inside their arrays, they can be logged only by console.log(a.a1, a.a2) kind of syntax

Share:
203,811

Related videos on Youtube

sbichenko
Author by

sbichenko

Updated on January 31, 2020

Comments

  • sbichenko
    sbichenko over 4 years

    Consider this example Javascript code:

    a = new Array();
    a['a1']='foo';
    a['a2']='bar';
    
    b = new Array(2);
    b['b1']='foo';
    b['b2']='bar';
    
    c=['c1','c2','c3'];
    
    console.log(a);
    console.log(b);
    console.log(c);
    

    Results in the Firebug console are as follows:

    For a (the '[]' had to be expanded by clicking on the '+' button):

    []      
    a1  "foo"   
    a2  "bar"
    

    For b:

    [undefined, undefined]
    

    For c:

    ["c1", "c2", "c3"]
    

    My questions are:

    1. Am I using the array['key']='value' syntax correctly?
    2. Why isn't array b working as expected?
    3. Why are arrays a and c displayed differently in the console? It also seems that jQuery is unable to iterate through the array a with it's .each() method.
    4. Could you reccomend any good tutorials on Javascript array behaviour?

    NOTE: Google Chrome's Firebug displays only [] for array 'a', without the option to expand it.

    EDIT: Alright, it seems that arrays in Javascript have only numerical keys, so adding a string as a key name makes an object out of an array. But why doesn't jQuery's .each work with it?

    $.each(a, function ()
        {
        alert ('derp');
        })
    

    This code, appended to the script, produces no alerts.

    • Michael Berkowski
      Michael Berkowski over 12 years
      You're confusing JavaScript's array objects with associative arrays available in languages like PHP. JavaScript arrays use numeric indices only. Using the syntax a['a1'] = val adds a property a1 to the object a, not an array value.
    • RightSaidFred
      RightSaidFred over 12 years
      @P.Brian.Mackey: Probably because this sort of question has been asked plenty of times on SO.
    • RightSaidFred
      RightSaidFred over 12 years
      @exizt: Firebug and similar tools make assumptions about what you want displayed. They're not necessarily a prefect representation of the language, though as answered below, it is usually best to only rely on numeric properties in JavaScript Arrays.
    • yairr
      yairr over 12 years
      @RightSaidFred - So are you suggesting the question is a repeat, but the answer is new?
    • RightSaidFred
      RightSaidFred over 12 years
      @P.Brian.Mackey: The question doesn't show any research effort, so it doesn't surprise me that it wasn't upvoted. I downvoted it for that very reason. People seem to like the answer, so it was upvoted. The expectation is on the asker to first do research.
    • sbichenko
      sbichenko over 12 years
      What exactly would count as "research" in this case? Could you show me what search queries I should've used to find the right answer?
  • Rodolphe
    Rodolphe over 12 years
    And regarding the difference between a and b, I think it comes from the declaration b = new Array(2);. Here you're saying "my numerically-indexed array has 2 items". And since you're puting nothing into b[0] and b[1], that explains the 2 undefined you get in Firebug.
  • sbichenko
    sbichenko over 12 years
    I see, thanks! But why doesn't jQuery's .each() work with the 'a' array? (See edit)
  • yairr
    yairr over 12 years
    It is interesting to note how firebug treats a as an object that contains an array element. But, it treats b as an array with no visible properties (though the properties do exist). Where the only difference is the parameter passed to the Array constructor. I wonder why this is?
  • jfriend00
    jfriend00 over 12 years
    @exizt - jQuery's .each() method has to try to figure out if the item you pass it is an object or an array in order to figure out how to iterate it. If it's an array, it uses the array elements in the .each() iteration. In your case, you gave it an array so therefore it treats it as an array, but the array has no elements in the actual array so, there's nothing to iterate. If you change to a = {}; as the initialization, then it would work with jQuery's .each().
  • Navin Israni
    Navin Israni almost 10 years
    @jfriend clarified my own doubt in my answer :P