ES6 (ECMAScript 6) is the standard for the upcoming new version of the JavaScript language, codenamed harmony (meaning harmony, obviously it has not kept up with the pace of our country, we have entered the Chinese Dream version). The last time a standard was formulated was ES5, which was released in 2009. The standardization work of ES6 is currently in progress, and the officially finalized version is expected to be released in December 2014. But most standards are already in place, and browser support for ES6 is being implemented.
ES6 adds some new features to arrays, and these new features can be applied to your own business layer so far. In this section, we will summarize how to use some of the new features provided by ES6 for arrays.
Two static methods provided by ES6:
Array.from
Array.of
ES6 provides methods for manipulating, filling and filtering arrays:
Array.prototype.copyWidthin
Array.prototype.fill
Array.prototype.find
Array.prototype.findIndex
There are methods about array iteration in ES6:
Array.prototype.keys
Array.prototype.values
Array.prototype.entries
Array.prototype[Symbol.iterator]
The following mainly looks at the use of these methods.
Array.from()
The Array.from() method is mainly used to convert two types of objects (array-like objects [array-like objects] and traversable objects [iterable]) into real arrays.
In ES5, the following method is often used to convert an array-like object into an array:
function cast () { return Array.prototype.slice.call(arguments); } cast('a','b','c','d'); // ["a", "b", "c", "d"]
Or you can also write:
function cast () { return [].slice.call(arguments); } cast('a','b','c','d'); // ["a", "b", "c", "d"]
In ES6 you can use Array.from to convert an array-like object into a real array.
The so-called array-like object has only one essential characteristic, that is, it must have a length attribute. Therefore, any object with a length attribute is an array-like object and can be converted into a real array through the Array.from method.
let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 } console.log(Array.from(arrayLike)); // ["a","b","c"]
In ES6, the spread operator (...) can also convert some data structures into arrays. It just needs to call the iterator interface Symbol.iterator behind the scenes.
function cast (){ return [...arguments] } cast('a','b','c'); // ["a","b","c"]
It is worth noting that if an object does not deploy a traverser interface, the spread operator cannot be used to convert an array-like object into an array.
Array.from accepts three parameters, but only input is required:
input: Array-like objects and traversable objects you want to convert
map: Similar to the map method of an array, it is used to process each element and put the processed value into the returned array
context: this
used in binding map
As long as the data structure of the iterator interface is deployed, Array.from can convert it into an array:
let arr = Array.from('w3cplus.com') console.log(arr); // ["w","3","c","p","l","u","s",".","c","o","m"] let namesSet = new Set(['a', 'b']) let arr2 = Array.from(namesSet) console.log(arr2); //["a","b"]
The above code, because both the character string and the Set structure have iterator interfaces, can be converted into a real array by Array.from. If the parameter is a real array, Array.from will also return an identical new array:
let arr = Array.from([1, 2, 3]); console.log(arr); // [1,2,3]
As mentioned before, Array.from can also accept a second parameter, which is similar to the map method of an array. It is used to process each element, and the processed value is put into the returned array:
Array.from(arrayLike, x => x * x); // 等同于 Array.from(arrayLike).map(x => x * x); Array.from([1, 2, 3], (x) => x * x) // [1, 4, 9]
If the this keyword is used in the map function, you can also pass in the third parameter of Array.from to bind this.
Array.from() can convert various values into real arrays and also provides map function. What this actually means is that as long as you have a primitive data structure, you can first process its value and then convert it into a canonical array structure, and then you can use a large number of array methods.
Array.from({ length: 2 }, () => 'jack') // ['jack', 'jack']
In the above code, the first parameter of Array.from specifies the number of times the second parameter is run. This feature makes the usage of this method very flexible.
Another application of Array.from() is to convert a string into an array and then return the length of the string. Because it can correctly handle various Unicode characters, it can avoid the bug that JavaScript counts Unicode characters larger than uFFFF as two characters.
function countSymbols(string) { return Array.from(string).length; }
Using Array.from() can also return various data types:
function typesOf () { return Array.from(arguments, value => typeof value) } typesOf(null, [], NaN) // <- ['object', 'object', 'number']
You can also use the map method to implement the function of the above code:
function typesOf (...all) { return all.map(value => typeof value) } typesOf(null, [], NaN) // <- ['object', 'object', 'number'] Array.of
Use the Array.of method to convert a set of values into an array.
Array.of = function of () { return Array.prototype.slice.call(arguments) }
But you cannot use Array.of instead of Array.prototype.slice.call, they behave differently:
Array.prototype.slice.call([1, 2, 3]) // <- [1, 2, 3] Array.of(1, 2, 3) // <- [1, 2, 3] Array.of(3) // <- [1]
The main purpose of this method is to make up for the shortcomings of the array constructor Array(). Because the number of parameters is different, the behavior of Array() will be different:
new Array() // <- [] new Array(undefined) // <- [undefined] new Array(1) // <- [undefined x 1] new Array(3) // <- [undefined x 3] new Array(1, 2) // <- [1, 2] new Array(-1) // <- RangeError: Invalid array length
Array.of can basically be used to replace Array() or new Array(), and there is no overloading due to different parameters, and their behavior is very uniform:
Array.of() // <- [] Array.of(undefined) // <- [undefined] Array.of(1) // <- [1] Array.of(3) // <- [3] Array.of(1, 2) // <- [1, 2] Array.of(-1) // <- [-1]
Array.of方法可以使用下面的代码来模拟实现:
function ArrayOf(){ return [].slice.call(arguments); }
copyWidthin
copyWidthin方法可以在当前数组内部,将指定位置的数组项复制到其他位置(会覆盖原数组项),然后返回当前数组。使用copyWidthin方法会修改当前数组。
Array.prototype.copyWithin(target, start = 0, end = this.length)
copyWidthin将会接受三个参数:
target: 这个参数是必须的,从该位置开始替换数组项
start: 这是一个可选参数,从该位置开始读取数组项,默认为0,如果为负值,表示从数组的右边向左开始读取
end: 这是一个可选参数,到该位置停止读取的数组项,默认等于Array.length。如果为负值,表示倒数
我们先来看一个简单的示例,下面声明了一个items数组:
var items = [1, 2, 3, ,,,,,,,]; // <- [1, 2, 3, undefined x 7]
下面的代码将在数组items的第六个位置开始粘贴数组项。粘贴过去的数组项是从items的第二位开始到第三位置结束。
items.copyWithin(6, 1, 3) // <- [1, 2, 3, undefined × 3, 2, 3, undefined × 2]
下面是更多例子:
// 将3号位复制到0号位 [1, 2, 3, 4, 5].copyWithin(0, 3, 4) // [4, 2, 3, 4, 5] // -2相当于3号位,-1相当于4号位 [1, 2, 3, 4, 5].copyWithin(0, -2, -1) // [4, 2, 3, 4, 5] // 将3号位复制到0号位 [].copyWithin.call({length: 5, 3: 1}, 0, 3) // {0: 1, 3: 1, length: 5} // 将2号位到数组结束,复制到0号位 var i32a = new Int32Array([1, 2, 3, 4, 5]); i32a.copyWithin(0, 2); // Int32Array [3, 4, 5, 4, 5] // 对于没有部署TypedArray的copyWithin方法的平台 // 需要采用下面的写法 [].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4); // Int32Array [4, 2, 3, 4, 5] Array.prototype.fill
Array.prototype.fill方法使用给定的值填充一个数组:
['a', 'b', 'c'].fill(0) // <- [0, 0, 0] new Array(3).fill(0) // <- [0, 0, 0]
上面这种方法用于空数组的初始化非常方便。数组中已有的元素会全部被抹去。
除此之外,Array.prototype.fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。
['a', 'b', 'c',,,].fill(0, 2) // <- ['a', 'b', 0, 0, 0] new Array(5).fill(0, 0, 3) // <- [0, 0, 0, undefined x 2]
Array.prototype.fill提供的值可以是任意的,不仅可以是一个数值,甚至还可以是一个原始类型:
new Array(3).fill({}) // <- [{}, {}, {}]
不过这个方法不可以接受数组的映射方法,不过可以接受一个索引参数或类似下面这样的方式:
new Array(3).fill(function foo () {}) // <- [function foo () {}, function foo () {}, function foo () {}] Array.prototype.find
Array.prototype.find方法用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的数组项,然后返回该数组项。如果没有符合条件的数组项,则返回undefined。
[1, 2, 3, 4, 5].find(item => item > 2) // <- 3 [1, 2, 3, 4, 5].find((item, i) => i === 3) // <- 4 [1, 2, 3, 4, 5].find(item => item === Infinity) // <- undefined
另外这种方法的回调函数可以接受三个参数,依次为当前的值、当前的位置和原始数组。
[1, 5, 10, 15].find(function(value, index, arr) { return value > 9; }) // 10 Array.prototype.findIndex
这个方法类似于.some和.find方法。像.some返回true;像.find返回item。如果array[index] === item则返回其index。
Array.prototype.findIndex方法主要是用来返回数组项在数组中的位置。其和Array.prototype.find方法非常类似,接受一个回调函数,如果符合回调函数的条件,则返回数组项在数组中的位置,如果所有数组项都不符合回调函数条件,则会返回-1。
[1, 2, 3, 4, 5].find(item => item > 2) // <- 2 [1, 2, 3, 4, 5].find((item, i) => i === 3) // <- 3 [1, 2, 3, 4, 5].find(item => item === Infinity) // <- -1
这个方法也可以接受第二个参数,用来绑定回调函数的this对象。
注:Array.prototype.find和Array.prototype.findIndex两个方法都可以发现NaN,弥补数组的indexOf方法的不足。
[NaN].indexOf(NaN) // -1 [NaN].findIndex(y => Object.is(NaN, y)) // 0
上面的代码中,indexOf方法无法识别数组的NaN成员,但是findIndex方法可以借助Object.is方法做到。
ES6遍历数组的方法
ES6提供了三个新方法:entries()、keys()和values(),用来遍历数组。它们都返回一个遍历器对象,可以用for...of循环进行遍历,唯一的区别是keys()是对数组的键名的遍历、values()是对数组键值的遍历,entries()方法是对数值的键值对的遍历。
for (let index of ['a', 'b'].keys()) { console.log(index); } // 0 // 1 for (let elem of ['a', 'b'].values()) { console.log(elem); } // 'a' // 'b' for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem); } // 0 "a" // 1 "b"
如果不使用for...of循环,可以手动调用遍历器对象的next方法,进行遍历:
let letter = ['a', 'b', 'c']; let entries = letter.entries(); console.log(entries.next().value); // [0, 'a'] console.log(entries.next().value); // [1, 'b'] console.log(entries.next().value); // [2, 'c']
总结
这里简单的总结了有关于ES6中数组的相关方法。说实在的,初次接触ES6,很多东西都看得云里来雾里去。这里只是整理了一下这方面的相关知识。
关于JavaScript学习笔记之ES6数组方法小编就给大家介绍到这里,希望对大家有所帮助!