Home  >  Article  >  Web Front-end  >  ECMAScript 6 will soon bring us a preview of new array operation methods_javascript skills

ECMAScript 6 will soon bring us a preview of new array operation methods_javascript skills

WBOY
WBOYOriginal
2016-05-16 16:22:061223browse

This article introduces the new array operation methods that ECMAScript 6 will bring us, and how to apply these new array features in existing browsers.

Note: I will use the terms constructor and class interchangeably.

Class method
Methods owned by Array itself.

Array.from(arrayLike, mapFunc?, thisArg?)

The basic function of Array.from() is to convert two types of objects into arrays.

Array-like objects

This type of object has length and index properties. The result of the DOM operator belongs to this class, such as document.getElementsByClassName().

Iterable objects

When this type of object takes a value, it can only take one element at a time. Arrays are iterable, just like the new array structures in ECMAScript, Map and Set.

The following code is an example of converting an array-like object to an array:

Copy code The code 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 is no forEach() method. This is why we need to convert it to an array before using this method.

Use Mapping via Array.from()
Array.from() is also an alternative to using map() with generics.

Copy code The code is as follows:

let spans = document.querySelectorAll('span.name');
// map(), generically:
let names1 = Array.prototype.map.call(spans, s => s.textContent);
// Array.from():
let names2 = Array.from(spans, s => s.textContent);

The second parameter in both methods is an arrow function.
In this example, the result of document.querySelectorAll() is an array-like object, not an array. This is why we cannot call map() directly. In the first example, in order to use forEach(), we convert the array-like object into an array. Here we use the generic method and the two-parameter version of Array.from(), eliminating the intermediate step.

Holes
Array.from() ignores missing elements - holes - in the array and treats them as undefined elements.

Copy code The code is as follows:

> Array.from([0,,2])
[ 0, undefined, 2 ]

This means that you can use Array.from() to create or fill an array:

Copy code The code is as follows:

> Array.from(new Array(5), () => '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) will be a better choice. The first is the two ways of the above example.

from()
in Array subclass Another use case for Array.from() is to convert an array-like object or iterable object to an instance of an array (Array) subclass. If you create an Array subclass MyArray and want to convert such an object into an instance of MyArray, you can simply use MyArray.from(). The reason this can be used is that in ECMAScript 6 constructors are inherited (the parent class constructor is the prototype of its subclass constructor).

Copy code The code is as follows:

class MyArray extends Array {
...
}
let instanceOfMyArray = MyArray.from(anIterable);

You can combine this functionality with mapping, completing the map operation in a place where you control the result constructor:

Copy code The code 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 an array literal. Especially when there is only one value and it is a number, the array constructor will fail. Please refer to this page for more information.

Copy code The code is as follows:

> new Array(3, 11, 8)
[ 3, 11, 8 ]
> new Array(3)
[ , , ,]
> new Array(3.1)
RangeError: Invalid array length

What should we do if we want to convert a set of values ​​into an instance of a numeric sub-constructor? This is the value of Array.of() (remember, the array subconstructor inherits all array methods, including of() of course).

Copy code The code 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 very convenient to wrap and nest the value in an array, without the weird processing method like Array(). But also pay attention to Array.prototype.map(), there are pitfalls here:

Copy code The code 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 to its callback. The last two are often overlooked (details).

Prototype methods
Many new methods will be available for array instances.

Iterating over arrays

The following methods will help complete iteration in the array:

Copy code The code is as follows:

Array.prototype.entries()
Array.prototype.keys()
Array.prototype.values()

Each of the above methods will return a string of values, but not as an array. They will be displayed one after another through the iterator. Let's look at an example (I'll use Array.from() to put the contents of the iterator in an array):

Copy code The code 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() with the for-of loop in ECMAScript 6 to easily decompose the iterated object into key-value pairs:

Copy code The code is as follows:

for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}

Note: This code can already run in the latest Firefox browser. t Firefox.

Find array elements

Array.prototype.find(predicate, thisArg?) will return the first element that satisfies the callback function. If no element satisfies the condition, it returns undefined. For example:

Copy code The code is as follows:

> [6, -5, 8].find(x => x < 0)
-5
> [6, 5, 8].find(x => x < 0)
undefined
Array.prototype.findIndex(predicate, thisArg?)

will return the index of the first element that satisfies the callback function. If no satisfying elements are found, -1 is returned. For example:

Copy code The code is as follows:

> [6, -5, 8].findIndex(x => x < 0)
1
> [6, 5, 8].findIndex(x => x < 0)
-1

Both find* methods will ignore holes, that is, they will not pay attention to undefined elements. The completion function signature of the callback is:

predicate(element, index, array)
Find NaN

through findIndex()

Array.prototype.indexOf() has a well-known limitation, that is, it cannot find NaN. Because it uses identity (===) to find matching elements:

Copy code The code is as follows:

> [NaN].indexOf(NaN)
-1

Using findIndex(), you can use Object.is(), which will not cause such problems:

Copy code The code is as follows:

> [NaN].findIndex(y => Object.is(NaN, y))
0

You can also take a more general approach and create a helper function elemIs():

Copy code The code is as follows:

> function elemIs(x) { return Object.is.bind(Object, x) }
> [NaN].findIndex(elemIs(NaN))
0
Array.prototype.fill(value, start?, end?)

Fill an array with the given value:

Copy code The code is as follows:

> ['a', 'b', 'c'].fill(7)
[ 7, 7, 7 ]

Holes will not receive any special treatment:

Copy code The code is as follows:

> new Array(3).fill(7)
[ 7, 7, 7 ]

You can also limit the start and end of your filling:

Copy code The code is as follows:

> ['a', 'b', 'c'].fill(7, 1, 2)
[ 'a', 7, 'c' ]

When can I use the new array methods?
Some methods are already available in the browser.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn