javascript array in depth

What is an Array in JavaScript?

A numerically indexed map of values.

Traditionally an array reserves a continuous allocation of memory of predefined length. In JavaScript this is not the case. A JavaScript array is simply a glorified object with a unique constructor and literal syntax and an additional set of properties and methods inherited from Array.prototype. If this means we make a small sacrifice in performance, it is more than compensated for by its ease of use and the power of its utilities. Unlike its counterparts in certain other languages, JavaScript arrays are a joy to use – this is something they definitely got right.

How do I create a JavaScript Array?

Lets start with the best way. In JavaScript, whenever there is a literal syntax for object creation it generally makes sense to use it.

1
2
3
4
5
6
7
8
9
10
11
//create a new, empty array
var a = [];
//add members to an existing array
a[0] = "Bob";
a[1] = "Mary";
a[2] = "Joe";
//or simply use push
a.push("Jane");
a.push("Carlos");
//create a new array and predefine some members
var b = ["Bob", "Mary", "Joe", "Jane", "Carlos"];

Alternatively you could use the new Constructor syntax. Apart from the obvious drawback of 5-9 additional assaults on your dainty finger pads (the “new” part is effectively optional) there is a more serious issue around ambiguity of intention:

1
2
3
4
5
6
7
8
//create a new array with 8 undefined members
var a = new Array(8);
//create a new array containing two predefined elements
var b = new Array(8,9);
a.length; //8
b.length; //2
a[0]; //undefined
b[0]; //8

These two declarations look strikingly similar yet produce entirely different results. Moreover, lets say someone edits the second statement because they now only want to predefine one element, the number 8, in array b. It’s quite likely they might modify it to the following (and who could blame them?):

1
2
//create a new array containing one predefined element
var b = new Array(8); //Wrong!

Of course this doesn’t do what they wanted. The only way to predefine an array with one primitive number is to use the literal syntax. (Thanks Peter and Dmitry for clarification)

Is there any advantage to using the new Array syntax?

Well it means you can define the length of your array at creation time. But since JavaScript arrays do not require an up front allocation of memory, and they can be lengthened at will any time, that’s a questionable requirement. (Several people pointed out webkit et al have built in optimization when Array length predefined – though there is nothing in the spec to suggest this)

What types of data can an Array contain?

An array can contain any object or primitive type. Multiple data types can co-exist in the same array.

How do I access an Array element?

Array elements are simply object properties and are accessed in the same way as other object properties. Since property identifiers are always strings, the array index is also a string, not a number. However when you use subscript notation (square brackets) to access the property, a number literal can also be used since it will be coerced to a string by the interpreter. Dot notation accessors will not work for array member access because literal property identifiers can’t start with a number (again, all these behaviours derive from generic object property rules, they are not array-specific)

1
2
3
var a = ["banana", Math.min, 4, "apple"];
a['1']; //min()
a[2]; //4

How should I iterate over the elements of an array?

Typically it makes sense to use the standard for loop:

1
2
3
4
var a = ["banana", Math.min, 4, "apple"];
for (var i=0; i < a.length; i++) {
    console.log(a[i]);
}

If your array is a long one you may be worried about the additional cost of requesting array.length on every iteration. To workaround this you can define the array length up front:

1
2
3
4
5
var a = makeBigArray();
for (var i=0,  aLength = a.length; i < aLength; i++) {
    console.log(a[i]);
}

Using a for…in statement for array iteration is not advised because you may also pick up enumerable properties from the prototype (see below)

Which properties are unique to Arrays?

The most important array property is length (strings and functions have length too but the array definition of length is unique)

Array.length is NOT a read-only value, you can set it as you wish.

ECMA specifies:
The length property of this Array object is always numerically greater than the name of every property whose name is an array index

In other words its (the numeric value of the last index) + 1

Array’s are not upper-bound. You can add an element at an index greater than (length – 1) and the length property will be modified based on the above definition. Array’s have a maximum length but its too big for you to worry about.

1
2
3
4
5
6
var a = [3,4,1];
a.length; //3
a[20] = 2;
a.length; //21
//element indexes 3-19 automatically created with value initialized to undefined
a[18]; //undefined

Arrays are lower-bound to zero. If you try to add a value at a negative index you will just be writing a regular object property (see also “associative arrays” below)

1
2
3
4
5
var a = [];
a[-1] = "giraffe";
a[-1]; //"giraffe"; //because still using a regular object property accessor
a.length; //0
a.toString(); //""

You can manipulate the contents of an existing array by updating its length value. If you reduce the length property of an existing array, members with indexes greater than or equal to the new length get discarded (this turns out to be the only way to remove indexes from an array – you can delete an element but this will only delete the value and leave the index in place – i.e. your array becomes “sparse” = it gets holes in it)

1
2
3
4
5
var a = [0,1,2,3,4,5,6];
a.length; //7
a.length = 5;
a.toString(); //"0,1,2,3,4"
a[6]; //undefined

Conversely if you increase the length of an existing array by n your array appears to get n new members, each with its value initialized to undefined – however as Dmitry Soshnikov points out, this is the standard response to accessing a non existent property. In reality nothing has changed except the array length.

1
2
3
4
5
6
7
8
var a = [0,1,2,3,4,5,6];
a.length; //7
a[9]; //undefined
a[59]; //undefined
a.length = 10;
a.toString(); //"0,1,2,3,4,5,6,,,"
a[9]; //undefined
a[59]; //undefined

There are two additional pseudo-properties of arrays: index and input. These properties are only present in arrays created by regular expression matches

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s