New Methods on All Arrays

Continuing the trend from ECMAScript 5, ECMAScript 6 adds several new methods to arrays. The find() and findIndex() methods are meant to aid developers using arrays with any values, while fill() and copyWithin() are inspired by use cases for typed arrays, a form of array introduced in ECMAScript 6 that uses only numbers.

The find() and findIndex() Methods

Prior to ECMAScript 5, searching through arrays was cumbersome because there were no built-in methods for doing so. ECMAScript 5 added the indexOf() and lastIndexOf() methods, finally allowing developers to search for specific values inside an array. These two methods were a big improvement, yet they were still fairly limited because you could only search for one value at a time. For example, if you wanted to find the first even number in a series of numbers, you’d need to write your own code to do so. ECMAScript 6 solved that problem by introducing the find() and findIndex() methods.

Both find() and findIndex() accept two arguments: a callback function and an optional value to use for this inside the callback function. The callback function is passed an array element, the index of that element in the array, and the array itself—the same arguments passed to methods like map() and forEach(). The callback should return true if the given value matches some criteria you define. Both find() and findIndex() also stop searching the array the first time the callback function returns true.

The only difference between these methods is that find() returns the value whereas findIndex() returns the index at which the value was found. Here’s an example to demonstrate:

  1. let numbers = [25, 30, 35, 40, 45];
  2. console.log(numbers.find(n => n > 33)); // 35
  3. console.log(numbers.findIndex(n => n > 33)); // 2

This code calls find() and findIndex() to locate the first value in the numbers array that is greater than 33. The call to find() returns 35 and findIndex() returns 2, the location of 35 in the numbers array.

Both find() and findIndex() are useful to find an array element that matches a condition rather than a value. If you only want to find a value, then indexOf() and lastIndexOf() are better choices.

The fill() Method

The fill() method fills one or more array elements with a specific value. When passed a value, fill() overwrites all of the values in an array with that value. For example:

  1. let numbers = [1, 2, 3, 4];
  2. numbers.fill(1);
  3. console.log(numbers.toString()); // 1,1,1,1

Here, the call to numbers.fill(1) changes all values in numbers to 1. If you only want to change some of the elements, rather than all of them, you can optionally include a start index and an exclusive end index, like this:

  1. let numbers = [1, 2, 3, 4];
  2. numbers.fill(1, 2);
  3. console.log(numbers.toString()); // 1,2,1,1
  4. numbers.fill(0, 1, 3);
  5. console.log(numbers.toString()); // 1,0,0,1

In the numbers.fill(1,2) call, the 2 indicates to start filling elements at index 2. The exclusive end index isn’t specified with a third argument, so numbers.length is used as the end index, meaning the last two elements in numbers are filled with 1. The numbers.fill(0, 1, 3) operation fills array elements at indices 1 and 2 with 0. Calling fill() with the second and third arguments allows you to fill multiple array elements at once without overwriting the entire array.

I> If either the start or end index are negative, then those values are added to the array’s length to determine the final location. For instance, a start location of -1 gives array.length - 1 as the index, where array is the array on which fill() is called.

The copyWithin() Method

The copyWithin() method is similar to fill() in that it changes multiple array elements at the same time. However, instead of specifying a single value to assign to array elements, copyWithin() lets you copy array element values from the array itself. To accomplish that, you need to pass two arguments to the copyWithin() method: the index where the method should start filling values and the index where the values to be copied begin.

For instance, to copy the values from the first two elements in an array to the last two items in the array, you can do the following:

  1. let numbers = [1, 2, 3, 4];
  2. // paste values into array starting at index 2
  3. // copy values from array starting at index 0
  4. numbers.copyWithin(2, 0);
  5. console.log(numbers.toString()); // 1,2,1,2

This code pastes values into numbers beginning from index 2, so both indices 2 and 3 will be overwritten. Passing 0 as the second argument to copyWithin() indicates to start copying values from index 0 and continue until there are no more elements to copy into.

By default, copyWithin() always copies values up to the end of the array, but you can provide an optional third argument to limit how many elements will be overwritten. That third argument is an exclusive end index at which copying of values stops. Here’s an example:

  1. let numbers = [1, 2, 3, 4];
  2. // paste values into array starting at index 2
  3. // copy values from array starting at index 0
  4. // stop copying values when you hit index 1
  5. numbers.copyWithin(2, 0, 1);
  6. console.log(numbers.toString()); // 1,2,1,4

In this example, only the value in index 0 is copied because the optional end index is set to 1. The last element in the array remains unchanged.

I> As with the fill() method, if you pass a negative number for any argument to the copyWithin() method, the array’s length is automatically added to that value to determine the index to use.

The use cases for fill() and copyWithin() may not be obvious to you at this point. That’s because these methods originated on typed arrays and were added to regular arrays for consistency. As you’ll learn in the next section, however, if you use typed arrays for manipulating the bits of a number, these methods become a lot more useful.