A closer look at the forEach() JavaScript array method

Before the Array.forEach() method, iterating through an array in JavaScript would involve using a for loop.

const beans = ['kidney', 'baked', 'black'];

for (let i = 0; i < beans.length; i++) {
  console.log(beans[i]);
}

// kidney
// baked
// black

Using Array.forEach() makes things a bit simpler.

beans.forEach(function(bean) {
  console.log(bean);
}

// kidney
// baked
// black

But what does the Array.forEach() method actually do?

All array methods are functions attached to the Array.prototype object. We want our method to execute a provided function to each element of the array. What would this method look like then? Under-the-hood, the method is still in fact using a for loop.

Array.prototype.forEach = function (callback) {
  if (callback && typeof callback === 'function') {
    for (var i = 0; i < this.length; i++) {
      callback(this[i], i, this);
    }
  }
};

The for loop will iterate through each item in the array, and pass in the current item in the loop, the current index, and the array itself as arguments to the callback provided. Because the method is attached to the prototype, it can use this to refer to the array itself.

Reimplementing the JavaScript Array.push() method

Adding elements to an array is a very common practice when using JavaScript, made easy by the push() method:

const newArray = ['senna', 'prost'];
newArray.push('hill');
// newArray becomes ['senna', 'prost', 'hill']

Let’s try and reimplement a simple version of what the Array.push() method is doing under-the-hood.

In a previous post, we learnt that every JavaScript array has a length property:

newArray.length;  // 3

The Array.length property of an array is the largest integer property name in the array plus one. Remember, the property name refers to the ‘key’ of an element, not the value. The above array is not dissimilar to this object:

const newArray_object = { '0':'senna', '1': 'prost', '2': 'hill'};

We also learnt that we can add an element to the end of array by utilising this length property:

newArray[newArray.length] = 'schumacher';
// newArray becomes ['senna', 'prost', 'hill', 'schumacher']

Given that methods are functions attached to the array prototype object, here is an example of how we could create our our own array object with a push method using our knowledge of the Array.length property:

newArray = {
    length: 0,
    push: function (value) {
        // Place the new value into the
        // next available integer key
        this[this.length] = value;

        // Update the length property
        this.length = this.length + 1;

        // Return the updated length
        return this.length;
    }
};

newArray.push('woods');
newArray.push('mickelson');

newArray[0] //  'woods'
newArray[1] //  'mickleson'
newArray.length  // 2

Arrays in JavaScript

JavaScript’s latest version (ES6) has introduced a number of new Array prototype methods. Over the next few blog posts I’ll go over the most useful of these in detail, including how each of them operate under-the-hood in order to fully understand how they work.

But first off we should understand what an array in JavaScript is. An array in JavaScript is an object. For example, we can create an array using an array literal:

const cricketers = ['amla', 'de villiers', 'smith', 'kohli'];

In our array, the first value will get the property name 0, and the second 1, and so on, allowing us to retrieve value from the array as follows:

cricketers[1];   // 'de villiers'

We can produce a very similar result by creating a new object literal:

const cricketers_object = {
    '0': 'amla',
    '1': 'de villiers',
    '2': 'smith',
    '3': 'kohli',
}

Both cricketers and cricketers_object are objects, and both have exactly the same property names and values. However, cricketers inherits from the Array.prototype, whereas cricketers_object inherits from the Object.prototype.

JavaScript arrays can contain elements of any value type, including nested arrays and objects:

const assortedArray = ['apple', '0.5', ['nested', 'array'], {'name': 'nested'}, true, false, null, undefined];

Array.length

The Array.length of an array is the largest integer property name in the array plus one, for example:

assortedArray.length    // 8

The length property can be set explicitly – setting it to less than the current number will delete those with a property name larger than the new length:

assortedArray.length = 2;
// assortedArray becomes ['apple', '0.5']

We can also append items to the end of an array by using:

assortedArray[assortedArray.length] = 'pineapple';
// assortedArray becomes ['apple', '0.5', 'pineapple']

However, we can rather use Array.push method to append items to the end of an array.

Deleting elements

We can use the delete operator on an array to remove elements, but that leaves a hole in the array, as all elements to the right of the deleted item will retain their property names:

delete assortedArray[0];
// assortedArray becomes [ undefined, '0.5', 'pineapple'

When to use an array instead of object?

There is a simple rule for this: if your property names are small sequential integers, use an array. Otherwise, use an object.