This article introduces ECMAScript 6 will bring us new array operation methods and how to apply these new array features in existing browsers.
Note: I will use the terms constructor and class alternately.
Class Methods
The method that the array itself has.
Array.from(arrayLike, mapFunc?, thisArg?)
The basic function of Array.from() is to convert two types of objects into arrays.
Array-like objects
This class of objects has properties of length and index. The result of the DOM operator belongs to this class, such as document.getElementsByClassName().
Iterable objects
When taking values, only one element can be taken at a time. Arrays are iterable, like the new array structure, map (Map) and set (Set) in ECMAScript.
The following code is an example of converting an array object into an array:
The code copy is as follows:
let lis = document.querySelectorAll('ul.fancy li');
Array.from(lis).forEach(function (li) {
console.log(node);
});
The result of querySelectorAll() is not an array, and there will be no method forEach(). This is why we need to convert this method to an array before using it.
Using Mapping via Array.from()
Array.from() is also an alternative to generics using map().
The code copy is as follows:
let spans = document.querySelectorAll('span.name');
// map(), generally:
let names1 = Array.prototype.map.call(spans, s => s.textContent);
// Array.from():
let names2 = Array.from(spans, s => s.textContent);
The second parameter in the two methods is an arrow function.
In this example, the result of document.querySelectorAll() is another class array object, not an array. This is why we cannot call map() directly. In the first example, in order to use forEach(), we convert the class array object into an array. Here we omit the intermediate steps through generic methods and two-parameter versions of Array.from().
Holes
Array.from() ignores missing elements - holes in the array, which will be treated as undefined elements.
The code copy is as follows:
> Array.from([0,,2])
[ 0, undefined, 2 ]
This means that you can use Array.from() to create or populate an array:
The code copy is as follows:
> Array.from(new Array(5), () => 'a')
[ 'a', 'a', 'a', 'a', 'a', 'a' ]
> Array.from(new Array(5), (x,i) => i)
[ 0, 1, 2, 3, 4 ]
If you want to fill an array with a fixed value, then Array.prototype.fill() (see below) would be a better choice. The first one is the two methods of the above example.
from() in an array (Array) subclass
Another use scenario for Array.from() is to convert an instance of an array object or an iterable object to an Array subclass. If you create an Array subclass MyArray and want to convert this type of object into an instance of MyArray, you can simply use MyArray.from(). The reason why this can be used is that in ECMAScript 6 constructors will inherit (the parent class constructor is the prototype of its subclass constructor).
The code copy is as follows:
class MyArray extends Array {
...
}
let instanceOfMyArray = MyArray.from(anIterable);
You can combine this function with mapping to complete map operation where you control the result constructor:
The code copy is as follows:
// from() determine the result's constructor via the receiver
// (in this case, MyArray)
let instanceOfMyArray = MyArray.from([1, 2, 3], x => x * x);
// map(): the result is always an instance of Array
let instanceOfArray = [1, 2, 3].map(x => x * x);
Array.of(...items)
If you want to convert a set of values into an array, you should use the array source text (array literal). Especially when there is only one value and it is a number, the constructor of the array goes on strike. For more information, please refer to.
The code copy is as follows:
> new Array(3, 11, 8)
[ 3, 11, 8 ]
> new Array(3)
[ , , , ]
> new Array(3.1)
RangeError: Invalid array length
So if we want to convert a set of values into an instance of a sub-constructor, what should we do? This is the value of Array.of() (remember, the array subconstructor will inherit all array methods, including of() of course).
The code copy is as follows:
class MyArray extends Array {
...
}
console.log(MyArray.of(3, 11, 8) instanceof MyArray); // true
console.log(MyArray.of(3).length === 1); // true
Array.of() will be quite convenient to wrap values in an array, without the weird way of handling Array(). But also pay attention to Array.prototype.map(), there is a pit here:
The code copy is as follows:
> ['a', 'b'].map(Array.of)
[ [ 'a', 0, [ 'a', 'b' ] ],
[ 'b', 1, [ 'a', 'b' ] ] ]
> ['a', 'b'].map(x => Array.of(x)) // better
[ [ 'a' ], [ 'b' ] ]
> ['a', 'b'].map(x => [x]) // best (in this case)
[ [ 'a' ], [ 'b' ] ]
As you can see, map() will pass three parameters into its callback. The last two are often overlooked (details).
Prototype methods
There are many new methods available for instances of arrays.
Iterating over arrays
The following method will help complete iteration in the array:
The code copy is as follows:
Array.prototype.entries()
Array.prototype.keys()
Array.prototype.values()
Each of the above methods returns a string of values, but will not be returned as an array. They will be displayed one by one through iterators. Let's look at an example (I'll put the contents of the iterator in an array using Array.from()):
The code copy is as follows:
> Array.from([ 'a', 'b' ].keys())
[ 0, 1 ]
> Array.from([ 'a', 'b' ].values())
[ 'a', 'b' ]
> Array.from([ 'a', 'b' ].entries())
[ [ 0, 'a' ],
[ 1, 'b' ] ]
You can combine entries() and for-of loops in ECMAScript 6 to easily disassemble the iterative object into a key-value pair:
The code copy is as follows:
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
Note: This code can already be run in the latest Firefox browser. t Firefox.
Find array elements
Array.prototype.find(predicate, thisArg?) returns the first element that satisfies the callback function. If no element satisfies the condition, it returns undefined. for example:
The code copy is as follows:
> [6, -5, 8].find(x => x < 0)
-5
> [6, 5, 8].find(x => x < 0)
undefined
Array.prototype.findIndex(predicate, thisArg?)
Returns the index of the first element that satisfies the callback function. If no satisfying elements are found, -1 is returned. for example:
The code copy is as follows:
> [6, -5, 8].findIndex(x => x < 0)
1
> [6, 5, 8].findIndex(x => x < 0)
-1
Both find* methods ignore holes, that is, they do not pay attention to undefined elements. The completion function signature of the callback is:
predicate(element, index, array)
Find NaN via findIndex()
Array.prototype.indexOf() has a well-known limitation, that is, it cannot find NaNs. Because it uses identity (===) to find matching elements:
The code copy is as follows:
> [NaN].indexOf(NaN)
-1
Using findIndex(), you can use Object.is(), which won't cause such a problem:
The code copy is as follows:
> [NaN].findIndex(y => Object.is(NaN, y))
0
You can also use a more general way to create a helper function elemIs():
The code copy is as follows:
> function elemIs(x) { return Object.is.bind(Object, x) }
> [NaN].findIndex(elemIs(NaN))
0
Array.prototype.fill(value, start?, end?)
Use the given value to fill an array:
The code copy is as follows:
> ['a', 'b', 'c'].fill(7)
[ 7, 7, 7 ]
Holes will not be treated with any special treatment:
The code copy is as follows:
> new Array(3).fill(7)
[ 7, 7, 7 ]
You can also limit the start and end of your fill:
The code copy is as follows:
> ['a', 'b', 'c'].fill(7, 1, 2)
[ 'a', 7, 'c' ]
When can I use the new array method?
There are some methods that can be used in the browser.