Understanding JavaScript Arrays

Note: This post is work-in-progress learning-note and still in active development and updated regularly.

The MDN Docs defines arrays as “an ordered set of values that you refer to with a name and an index“.

JavaScript (JS) objects hold one or more data types including numbers, strings and objects as key:value pairs. One of the requirements of JS objects is its key type can only be a ‘string‘. But often we also need to hold indexed collections data as item1, item2, item3, ..., itemN. Using JS objects, it is not possible to manage the order of the elements, for example inserting an item in between the existing ones. JS array, on the other hand, hold such ordered data types and its build-in methods & properties provide powerful tools to manage order of elements. Unlike JS objects, JS array cannot use 'string‘ as element indexes.

What is an Array?

Lets say we have lists of items, like car names, user names, product names etc. and to store a single item in a single variable would very cumbersome, take lot of space and difficult to read & maintain. For example, we have three cars Toyota, Ford, Honda and we want to assign them into their own variables, which could be done as follows:

//using single item per variable
let car1 = "Toyota";
let car2 = "Ford";
let car3 = "Honda";

//using array
let cars = ["Toyota", "Ford", "Honda"];
//access an item
cars[0]; //OUTPUT => "Toyota"

Using an array construct, the three car items (car1, car2, car3) were assigned to a single variable name cars (line 7) and square brackets  [] in an array. Now, each item can be accessed referring to an index number (line 9).

Array – the Basics

Array Syntax

A typical syntax for creating an array looks like as follows:

// array syntax
let arr_name = [item0, item1, ..., itemN];
let arr_name = new Array(item0, item1, ..., itemN);
let arr_name = Array(item0, item1, ..., itemN);

In the example above, the item0, item1, ..., itemN are refers to values of array’s element. The bracket [ ] syntax is called array literal or array initializer and preferred method of creating an array.

Array Literals
To quote from the MDN Document ” an array literal is a list of zero or more expressions, each of which represents an array element, enclosed in square brackets ([]). When you create an array using an array literal, it is initialized with the specified values as its elements, and its length is set to the number of arguments specified.

Creating an Array

Lets create an array of 5 car names and initialize as cars using array literal [ ] and array constructor. using new array() method.

//Initialize an array with an integer 
let cars = ['Toyota', 'Ford', 'Honda', 'BMW', 'GM'];
//access first item
cars[0];// OYTPUT => "Toyota"
//access length
console.log(cars.length); // 5

// Initialize array with array constructor
let cars = new Array('Toyota', 'Ford', 'Honda', 'BMW', 'GM');
//access first item
cars[0];// OYTPUT => "Toyota"

In the example above, both the cars array created using literal array with square brackets [ ] and index constructor new array() methods are exactly similar and produce similar outputs (lines 4 & 11). Because the constructor method is known to have inconsistencies and may produce unexpected results, the literal method is preferred method for creating new arrays.

Array with Mixed data Types

Although arrays are commonly used to list similar data types, an array can contain any data types or mix data types including object, function, string, null or another arrays.

// mix of values
let myCar = [
  'Toyota',             // string
   {model: 'Corolla' }, // object
   function() {         // function
      console.log('My Toyota') 
      },
   [ "Black", "Engine" ], // array
   true,                 // Boolean
   null,                 // empty
   2018,                 // integer
];

// access object at index 0 & 1
myCar[0]; //OUTPUT => Toyota
console.log( myCar[1].model ); //OUTPUT => Corolla
// get the function at index 3 and run it
myCar[3](); //OUTPUT => My Toyota
// access array item at index 0
myCar[3][0]; //OUTPUT => Black

// array check
typeof myCar;// => Object
Array.isArray(Mycar);// => true

In the example above, myCar array is initialized with mixed data types: a string 'Toyota', object {model: 'Corolla'}, and a function function() {console.log('My Toyota')}. The output of Array.isArray() methods confirms that it is an array (line 11).

Array Length Property

The length property of an array returns the length of an array (the number of array elements).

//Access array item
let array = ['one', 'two', 'three', 'four'];

//access first item
array[0]; //OUTPUT => one
//access second item
array[2]; //OUTPUT => three
//access last item
array[3]; //OUTPUT => four

//access array length
array.length; //OUTPUT => 4

JS arrays are indexed stating at 0 and not 1. What that means is that the length property always returns the highest index (last item) plus one stored in the array. In the example above, there are 4 items that are assigned to an array array (line 2). When we access the first one, it is indexed as 0 (line 5), the last item four is indexed as 3 (line 9) and the length array is 4 (line 12) as a proof that array indexing starts at 0.

Accessing an Array Item

In the previous section, we discussed that JS arrays are zero-indexed: first item indexed at 0 and the last item indexed at length property minus 1. Lets examine these features in our cars array with a list of five car names.

//Access array item
let cars = ['Toyota', 'Ford', 'Honda', 'BMW', 'GM'];

//access firs item
console.log(cars[0]); // Toyota
//access last item
console.log(cars[cars.length - 1]); // GM
//access full array
console.log(cars); //OUTPUT => (5) ["Toyota", "Ford", "Honda", "BMW", "GM"]

In the example above, first item of cars array 'Toyota‘ is indexed at 0 (line 5) and the last item of the array GM is the value of length - 1 (line 7). The full array list is accessed with cars which returns as object property (line 9). The following table shows how cars array is indexed:

Toyota Ford Honda BMW GM
0 1 2 3 4

Index number of a specific item in an array (eg.  cars), can be accessed using indexOf() method. Lets say we want to know the index number of our 'Honda' item, we can find its index number as shown (line 11) below, which returns 2 as also shown in the index table (above).

//find index of an array item
cars.indexOf("Honda");  // OUTPUT => 2

//access indexOf not existing item
cars.indexOf("Lexus");  // OUTPUT => -1
//access not index item
cars[6]; //OUTPUT => undefined

Accessing an item indexOf() to access an item that does not exit in the array (eg. "Lexus") returns -1 (line 14). Likewise, if non-existing index number (eg. 6, our highest array is index at 4) is used to access an item from our Cars array, it returns undefined (line 16).

Arrays are Objects

To quote from The Modern JavaScript Tutorial: “An array is a special kind of object. The square brackets used to access a property arr[0] actually come from the object syntax. Numbers are used as keys. They extend objects providing special methods to work with ordered collections of data and also the length property. But at the core it’s still an object. Remember, there are only 7 basic types in JavaScript. Array is an object and thus behaves like an object“.

//array initialization
let myCar = ["Toyota", "Corolla", 2018];
//check an array
typeof myCar; //"object"

//Object initialization
let myCar = {make: "Toyota", model: "Corolla", year: 2018};
//access an object
typeof myCars; // "object"

JS arrays are ordered indexes where as JS objects are named indexes. JS arrays are objects at their base. Lets examine some of these features in the above example where values of car properties (Toyota, corolla, 2018) are assigned as myCar array (line 2) and as myCar object with type:value properties (line 7). Now, if we access myCar  array (line 4) and myCar object (line 9) using typeof operator, it returns object in both cases, confirming both are object data types.

Recognizing an Array

In our previous examples, we observed that the typeof operator returned object in both myCar array and myCar object. This is because JS array is a special object. To solve this problem ECMAScript 5 defines a new method Array.isArray() to identify if a variable is an array? If it is an array, it returns true and false otherwise.

//array initialization
let myCar = ["Toyota", "Corolla", 2018];

//Array.isArray()
Array.isArray(myCar); // true  -- not consitent result
//instanceof
myCar instanceof Array; // true

//Object initialization
let myCar = {make: "Toyota", model: "Corolla", year: 2018};

//instanceof
myCar instanceof Array; // false
//Array.isArray()
Array.isArray(myCar); // false

In the example above (which was defined in previous section), Array.isArray() method was used to determine whether myCar array was an array? (line 5), it returned true confirming it was an array. When it was checked passing myCar object (line 15) it returned false indicating it was not an array.

Other operator instanceof is also used to determine if an object was created using a given constructor. When we myCar array was accessed using instanceof whether it was created with an array (line 7), it returned true confirming that it was an array. On the other hand when instanceof operator was accessed with myCar created with object constructor (line 13), it returned false confirming it was not an array.

Modifying Items in Array

An array can be modified by adding items, removing items or overwriting any values just like in an ordinary variable or an object. The real strength of JS arrays are in built-in methods and properties which we will discuss separately.

Tip: Major strength of JS arrays is its properties and build-in methods.

Adding items in Array

Items in an existing array can be added by assigning a value to the next index.

//initialize array
let myCar = ["Toyota", "Corolla", 2018];
//access myCar
myCar;
//OUTPUT
(3) ["Toyota", "Corolla", 2018]

//add an item
myCar[3] = "Black";
//access myCar items
myCar;
// OUTPUT
(4) ["Toyota", "Corolla", 2018, "Black"]

In the example above, myCar array has three items indexed from 0 to 2.  If we want to add an item, for example a color,  to our myCar array, we can assign color value 'Black' to its next index i.e. 3 (line 9). Now myCar array has 4 items and Black being its last [4] index (line 13)

If we skipped an index to add an item, it creates a gap in the index and outputs as empty array value.

//add item with skipping index
myCar[4] = "Red";
//access array items
myCar;
//OUTPUT
(5) ["Toyota", "Corolla", 2018, empty, "Red"]

//accessing an extra item
myCar[6]; //OUTPUT => undefined

In the example above, we added an item to myCar array (line 2) with 0 to 2 indices and assign a 'Red' color value to index 4 by skipping its next index (line 15), it returned empty index value to its missing index (line 19) thus creating a whole in our array. Likewise, if we access an extra item from an array, it returns unidentified value (line 22).

These kind of issues are avoided by using built-in methods like push() and unshift() to append items to the beginning and end of an array.

Deleting Items in Array

An item from an array can be removed or deleted using one of the built-in pop() method which removes item from last index.

//Remove item from the end of index
myCar.pop();

//access myCar array
myCar; 
//OUTPUT 
(2) ["Toyota", "Corolla"]

Using our myCar array (line 2) example above, lets remove the last item '2018' from the array using build-in pop() method (line 24). When access myCar array now, it removed last index item 2018 (line 29).

Overwriting Values

Just like in a regular variable, a given value in an array can be overwritten by assigning a new value using an assignment operator.

//assign Camry to the second item
myCar[1] = "Camry";

//access myCar array
myCar; 
//OUTPUT 
(2) ["Toyota", "Camry"]

Using the same myCar array (line 2) example above, lets overwrite the value of car model 'Corolla' with 'Camry' at index 1 (second item) in myCar array (line 31). Now when we access myCar array (line 34) its output (line 36) shows its previous 'Corolla' value (line 29) has been overwritten with a new value of 'Camry'.

Note: In the example above, we briefly looked at how an array can be modified by adding, deleting or overwriting values. We will look at array modification in more detail by using array methods in a separate learning-note post.

Increasing/Decreasing Array Length

In earlier Array Length Property section, we defined array length property. In this section, we will use array.length property to modify items in an array.

//initialize array item
let cars = ['Toyota', 'Ford', 'Honda', 'BMW', 'GM'];

//access array length
console.log(cars.length); //OUTPUT => 5

//assign new value to array length 
cars.length = 3;
console.log(cars);// OUTPUT => (3) ["Toyota", "Ford", "Honda"]

//assign zero value to array length
cars.length = 0;
console.log(cars); //OUTPUT => [ ] empty

// re-assign a value to array length
cars.length = 5;
console.log(cars); //OUTPUT =>(5) [empty × 5]

In the example above, cars array is initialized with five car brands (line 2). When we access cars array length it returns its expected value 5 (line 5). Array length property can also be assigned while creating an array.

Lets decrease the length of cars array from 5 items (line 5) to 3 items by assigning a new length property(line 8). Now, its output shows that cars array length has been decreased to three (line 9) and 2 items (BMW, GM) have been removed. If we assigned a value of zero to cars array length (line 12), it removes all the items and now our cars array is empty (line 13). By re-assigning an array length value of 5 (line 16), we can’t restore deleted (truncated) items to our cars array, it logs 5 empty items (line 17).

Built-in array methods & properties can be used to modify array in much desirable way.

Looping Through Array Items

Array length property was discussed in the previous section. Now we can make use the length property & for keyword to loop through an entire array to print out each index number and index value to the browser console.

//initialize an array with item
let cars = ['Toyota', 'Ford', 'Honda', 'BMW', 'GM'];
//Loop through with for
for (let i = 0; i < cars.length; i++) {
  console.log(i, cars[i]);
}

//OUTPUT
0 "Toyota"
1 "Ford"
2 "Honda"  
3 "BMW"
4 "GM"

Revisiting our cars array example above, the entire cars array of five car items is loop through using for keyword and cars.length property (lines 4-6) to printout cars array index number and index value (lines 9-13).

With <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of" target="_blank" rel="noopener">for...of</a> Statement

Array items can be loop through using <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of" target="_blank" rel="noopener">for...of</a> statement too.

//Access array item
let cars = ['Toyota', 'Ford', 'Honda', 'BMW', 'GM'];
//Loop through with for ..of
for (let car of cars) {
  console.log(car);
 }

//OUTPUT
Toyota
Ford
Honda
BMW
GM

Using our earlier cars array example with with five car items,  we loop through the entire cars array with for...of statement (lines 4-6) to printout array list (lines 9-13). Unlike the for loop, for...of loop does not retrieve the index number of array items.

Wrapping Up

JavaScript arrays are “special object” data types that hold an ordered set of values that are referred with a name and an index. In this learning-note post, we covered creating and identifying array, modifying an array and looping through array items. In the next learning-note post we will cover build-in array methods & properties.

NEXT: Learning JavaScript Array Methods.

Useful Resources & Links

While preparing this post, I have referred the following references extensively. Visit original link for additional information.