Good news, in June 2016 ECMAScript 2016 was approved. It contains the features that passed the stage 4, which means finished, of the TC39 process:

- The array method
`includes()`

- The exponentiation operator
`base ** exponent`

This edition is smaller than ECMAScript 2015, but it doesn't mean less important. Still it has details that you should know before using the new features.

The new method `array.includes(item, [fromIndex])`

allows to determine if an array contains a specific element. The precedent approach, less comfortable, to verify an element existence is to use `array.indexOf(item) !== -1`

.

The difference between the two of course is the shorter usage of `include()`

. However these methods use different equality algorithms and threat variously the empty slots in array.

The exponentiation operator `**`

has edge cases when it comes to `NaN`

.

The current article covers the details about ES2016 features with informative examples. Also it makes a comparison with older approaches in terms of compatibility, so you could migrate JavaScript code without surprises.

Before I go on, let me recommend something to you.

The path to becoming good at JavaScript isn't easy... but fortunately with a good teacher you can shortcut.

Take "Modern JavaScript From The Beginning 2.0" course by Brad Traversy to become proficient in JavaScript in just a few weeks. Use the coupon code DMITRI and get your 20% discount!

## 1. The array method includes()

The array method `includes(element, [fromIndex])`

determines whether an array contains a specific `element`

and returns the corresponding *boolean* (`true`

if `element`

is found, `false`

otherwise). An optional argument `fromIndex`

allows to search from a specific index.

Let's see some basic examples:

let months = ['June', 'July', 'August'];months.includes('June'); // => truemonths.includes('January'); // => false

`'June'`

element exists in `months`

array, so `includes()`

method returns `true`

. For a non available `'January'`

element, the method returns `false`

.

Notice that `includes()`

requires the searched element to match by type, because it uses for comparison the same value zero algorithm (a slight modified version of strict equality):

let items = ['1', 5, 8];items.includes(1); // => falseitems.includes(8); // => true

`items`

contains a string `'1'`

. However when searching for a number `items.includes(1)`

there is no match (`false`

is returned), because `'1'`

and `1`

are different types (string and number correspondingly).

When searching for objects, the method will match only references to the same object:

class Season { constructor(name) { this.name = name; }}let winter = new Season('Winter');let summer = new Season('Summer');let seasons = [winter, new Season('Summer')];seasons.includes(winter); // => trueseasons.includes(summer); // => false

`seasons.includes(winter)`

returns `true`

, because `winter`

variable is an object reference contained in `seasons`

.

On the other hand `seasons.includes(summer)`

returns `false`

, since the collection does not have an item that references `summer`

object. `new Season('Summer')`

(indicated in the array literal) is a reference to a different instance, thus not equal to `summer`

.

The `includes()`

method is available in typed arrays too:

let int8Array = Int8Array.from([17, 25]);int8Array.includes(17); // => true

### 1.1 Searching from an index

The method `array.includes(element, [fromIndex])`

accepts a second optional parameter `fromIndex`

, which enables searching from a specific index:

- For a number greater or equal to zero and less than array length, it indicates the index to start the search.
- For a number greater or equal to the array length,
`includes()`

always returns`false`

. - For a negative number, the search starts from a computed index:
`array.length + fromIndex`

. - If not specified, it defaults to
`0`

.

Let's follow an example:

let countries = ['UK', 'USA', 'Ireland', 'France'];countries.includes('UK', 1); // => falsecountries.includes('Ireland', 1); // => truecountries.includes('USA', 6); // => false

`'UK'`

element has index `0`

in `countries`

. However the search starts from `1`

and the index `0`

is skipped, so the element is not found.

`'Ireland'`

has index `2`

, thus the search `countries.includes('Ireland', 1)`

from index `1`

is able to find it.

The `'USA'`

element is checked from index `6`

, which is bigger than the array length `4`

. `includes()`

method for such situations returns `false`

.

For a negative from index parameter, the search starts from `array.length + fromIndex`

up to the end of array:

let numbers = [56, 11, 58, 89, 100];numbers.includes(11, -2); // => falsenumbers.includes(89, -2); // => true

The index to begin searching parameter is a negative number `-2`

and the search starts from index `5 - 2 = 3`

. The searched `11`

is compared only with `89`

and `100`

elements, so there is no match.

When searching for `89`

element with the same `-2`

offset, it is a match.

### 1.2 Searching for NaN

`includes()`

method uses same value zero comparison algorithm (see here why), which is a modified version of the strict equality comparison.
The main difference between the two is `NaN`

with `NaN`

equality consideration:

- Same value zero considers that
`NaN`

is**equal**with`NaN`

- Strict equality considers that
`NaN`

is**not equal**with`NaN`

Because `includes()`

uses the *same value zero comparison*, it is possible to identify `NaN`

elements:

let weirdNumbers = [-1, 100, NaN];weirdNumbers.includes(NaN); // => true

`weirdNumbers`

contains a `NaN`

, so `includes()`

method is able to find it.

`indexOf()`

array method has a different behavior in this situation, because it uses the *strict equality comparison*. Even if the array contains `NaN`

, `indexOf()`

returns `-1`

(meaning element not found):

let weirdNumbers = [-1, 100, NaN];weirdNumbers.indexOf(NaN); // => -1NaN === NaN; // => false

`weirdNumbers`

contains `NaN`

, however `indexOf()`

returns `-1`

.

Strict equality operator `===`

uses the same comparison algorithm, so `NaN === NaN`

is `false`

too.

Even if `includes()`

can find `NaN`

, it is best to code your application not to generate `NaN`

(which indicates that a wrong operation on numbers was applied).

### 1.3 Searching in a sparse array

An array in JavaScript is *sparse* when it contains empty slots (a.k.a. holes), i.e. the elements do not have contiguous indexes starting from `0`

. Sparse arrays can be created using:

- An array literal with missing element between commas
`[4, ,5]`

- An array constructor
`new Array(n)`

, where`n`

is a number - After applying
`delete array[index]`

operator

Let's see how an array literal creates a sparse array:

let sparseArray = [1, , 3];sparseArray[1]; // => undefinedsparseArray[2]; // => 3

`sparseArray`

contains an empty slot at index `1`

. Accessing an empty slot `sparseArray[1]`

evaluates to `undefined`

.

`includes()`

method **does not skip** the holes in array during the search iteration. Because accessing a hole evaluates to `undefined`

, calling `includes(undefined)`

returns a match when a hole is encountered:

let sparseArray = [1, , 3];sparseArray.includes(undefined); // => true

Since `sparseArray`

has an empty slot at index `1`

, executing `sparseArray.includes(undefined)`

returns `true`

.

Many other array methods **do skip** the empty slots, as their array iteration algorithm verifies if the element exists.

This rule applies to `indexOf()`

method too:

let sparseArray = [1, , 3];sparseArray.indexOf(undefined); // => -1

`indexOf()`

method returns `-1`

when searching for `undefined`

in an array with holes.

Of course, the general rule is to avoid at all dealing with sparse arrays.

### 2. The exponentiation operator

The exponentiation operator `base ** exponent`

raises the `base`

to the power `exponent`

.

Let's consider some examples:

2 ** 3; // => 85 ** 2; // => 250.5 ** 1; // => 0.5

The appropriate equivalent of this operator is `Math.pow(base, exponent)`

function.

It is possible to combine the exponentiation with an assignment `**=`

for a shorter form:

let num = 2;num **=4;num; // => 16

When combining the unary minus operator `-number`

with the exponentiation: `-x ** y`

, JavaScript first evaluates `x`

to power `y`

, then applies the minus sign to the result. Exponentiation has a higher priority over the unary minus operator.

The execution of `-x ** y`

is equivalent to `-(x ** y)`

. For instance `-5 ** 2`

equals to `-25`

.

### 2.1 Exponent special cases

Any number, including `NaN`

, powered to `0`

exponent evaluates to `1`

:

25 ** 0; // => 1NaN ** 0; // => 1Infinity ** 0; // => 1

If the exponent is `NaN`

, the exponentiation result is always `NaN`

, for any base value:

25 ** NaN; // => NaN-5 ** NaN; // => NaNNaN ** NaN; // => NaN

### 3. Finale

ECMAScript 2016 does not introduce big changes in the language. But it's the beginning of the JavaScript certain progress in smaller steps.

Without doubt `includes()`

is a long-awaited method to check the existence of an element. The workaround used before that `indexOf(item) !== -1`

is not a comfortable alternative.

`includes()`

method handles differently `NaN`

and empty slots in arrays. In my opinion it evaluates these situations better and more predictable.
In the end it's ok to return `true`

when searching `NaN`

value in an array that contains a `NaN`

, instead of `-1`

(missing) like `indexOf()`

does.

You probably won't deal a lot with the exponentiation operator, however a short form to raise to power it's nice to have in the pocket.

We, developers, are creating the future of JavaScript. If you have an interesting idea about a new language feature, do not hesitate to contribute to ECMAScript.

*In your opinion, what important feature JavaScript still misses? Feel free to write a comment below.*