ECMAScript 2016: Array.prototype.includes

One of the two features that will be part of ECMAScript 2016 is the new Array.prototype.includes method. It determines whether an array contains a certain element and returns either true or false.

The second new feature will be the exponentiation operator **, which provides a little syntactic sugar for Math.pow.

Egghead Lesson: Check If an Array Contains an Item Using Array.prototype.includes

Array.prototype.includes vs. Array.prototype.indexOf

Up until now, you've probably compared the return value of the Array.prototype.indexOf method against -1 to check whether an array contains a certain value:

const numbers = [4, 8, 15, 16, 23, 42];

if (numbers.indexOf(42) !== -1) {
    // ...
}

The Array.prototype.includes method makes this check easier to read and more semantically meaningful to human readers:

const numbers = [4, 8, 15, 16, 23, 42];

if (numbers.includes(42)) {
    // ...
}

Notice how the if-condition almost reads like a regular English sentence. There's no more fiddling around with indices just to determine array membership.

Looking for NaN

However, there's one edge case in which indexOf and includes behave differently, and that is NaN. Because the strict comparison NaN === NaN returns false, the indexOf method will return -1 when searching for NaN in an array:

assert([NaN].indexOf(NaN) === -1);

Most of the time, this is likely not what you intended. The includes method fixes this behavior and returns true:

assert([NaN].includes(NaN) === true);

As you would expect, the signed zero values +0 and -0 are treated the same as well:

assert([+0].includes(-0) === true);
assert([-0].includes(+0) === true);

Providing a Start Index

The indexOf method accepts an optional second parameter named fromIndex that specifies at which index in the array to start the search:

assert([100, 200, 300].indexOf(100, 0) === 0);
assert([100, 200, 300].indexOf(100, 1) === -1);

For consistency, the includes method accepts this parameter as well:

assert([100, 200, 300].includes(100, 0) === true);
assert([100, 200, 300].includes(100, 1) === false);

A Polyfill for Array.prototype.includes

There's also a spec-compliant polyfill available on MDN that allows you to use Array.prototype.includes today without worrying about browser compatibility:

if (!Array.prototype.includes) {
  Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
    'use strict';
    var O = Object(this);
    var len = parseInt(O.length) || 0;
    if (len === 0) {
      return false;
    }
    var n = parseInt(arguments[1]) || 0;
    var k;
    if (n >= 0) {
      k = n;
    } else {
      k = len + n;
      if (k < 0) {k = 0;}
    }
    var currentElement;
    while (k < len) {
      currentElement = O[k];
      if (searchElement === currentElement ||
         (searchElement !== searchElement && currentElement !== currentElement)) { // NaN !== NaN
        return true;
      }
      k++;
    }
    return false;
  };
}

Further Reading

For more details, check out the original feature proposal by Domenic Denicola and Rick Waldron, the current spec draft, or the documentation on MDN.

Use the coupon code LAUNCHDAY for $10 off!

Learn React

Comments