Array.from()
Array.from方法用于将“类数组”对象和“可迭代”对象转为真正的数组。
类数组对象
下面这个对象就是类数组对象,只不过很罕见,它的唯一特征就是必须有length属性。同时它一般应该由类似于数组下标的键名,但不是必须。
1 2 3 4 5 6 7 8 9 10 11 12
| let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 };
// ES5的写法 var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的写法 let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
|
常见的类数组对象是NodeList,以及函数内部的arguments对象。Array.from都可以将它们转为真正的数组。
1 2 3 4 5 6 7 8 9
| let ps = document.querySelectorAll('p'); Array.from(ps); // 真正的数组
// arguments对象 function foo() { var args = Array.from(arguments); // 真正的数组 // ... }
|
可迭代对象
只要是部署了 Iterator 接口的数据结构,Array.from都能将其转为数组。
1 2 3 4 5
| Array.from('hello') // ['h', 'e', 'l', 'l', 'o']
let namesSet = new Set(['a', 'b']) Array.from(namesSet) // ['a', 'b']
|
上面代码中,字符串和 Set 结构都具有 Iterator 接口,因此可以被Array.from转为真正的数组。
克隆新数组
1
| Array.from([1, [2,3], 4])
|
跟扩展运算符(…)的对比
扩展运算符的介绍详见ES6的扩展运算符和剩余操作符的对比和应用。
- 相同点,都可以将部署了 Iterator 接口的数据结构转为数组。
- 不同点,
...
不能将类数组对象转化为真正数组;Array.from()可以。
Array.from()可以将字符串转为数组,然后返回字符串的长度。因为它能正确处理各种 Unicode 字符,可以避免 JavaScript 将大于\uFFFF的 Unicode 字符,算作两个字符的 bug。
1 2 3 4 5 6 7 8
| function countSymbols(string) { return Array.from(string).length; } ```
#### Array.of()
Array.of方法用于将一组值,转换为数组。 先来看`Array()`方法的缺陷,参数只有1个的时候,返回的数组并不是我们想要的,`Array()`方法把一个参数理解为数组的长度,然后建立了3个空元素的数组,通常这没什么用。
|
Array() // []
Array(3) // [, , ,]
Array(3, 11) // [3, 11]
Array(3, 11, 8) // [3, 11, 8]
1 2
| 如果采用Array.of方法,行为就统一了。
|
Array.of() // []
Array.of(3) // [3]
Array.of(3, 11) // [3, 11]
Array.of(3, 11, 8) // [3, 11, 8]
1 2 3 4
| #### copyWithin方法
copyWithin方法顾名思义是内部元素复制,就是用内部一部分元素,来替换内部另一部分元素。
|
.copyWithin(target, start = 0, end = this.length)
1 2 3 4 5 6 7 8
| 它接受三个参数。
* target(必需):从该位置开始替换数据。如果为负值,表示倒数。 * start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示倒数。 * end(可选):到该位置**前**停止读取数据,默认等于数组长度。如果为负值,表示倒数。
举例描述最清楚了:
|
[1, 2, 3, 4, 5].copyWithin(0, 3)
// 0表示从0位开始替换数据
// 3表示从3位开始拷贝数组,一直拷贝到末尾,所以拷贝了4,5
// 将4,5放到0位和1位,最后就是 [4, 5, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(0, 2, 4)
// 0表示从0位开始替换数据
// 2表示从2位开始拷贝数组,一直拷贝到4位前,所以拷贝了3,4
// 将3,4放到0位、1位,最后就是 [3,4, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(-1, 2, 4)
// -1表示从右数1位,也就是最后1位开始替换数据也就是说,数字5将被替换
// 2表示从2位开始拷贝数组,一直拷贝到4位前,所以拷贝了3,4
// 将3,4放到右数1位,最后就是 [1,2,3,4,3]
[1, 2, 3, 4, 5].copyWithin(-2, -4, -2)
// -1表示从右数2位开始替换数据,也就是说,4,5将被替换
// -4表示从右数4位,也就是左数1位开始拷贝数组,
// 一直拷贝到-2位前,也就是拷贝到数字4前面,也就是包含3,所以拷贝了2,3
// 将2,3放到右数2位,替换掉4,5,最后就是 [1,2,3,2,3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #### find方法和findIndex方法
##### find方法
find方法用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
##### find方法与filter方法的对比
find方法只返回遇到的第一个符合条件的数组成员,filter方法会返回符合条件的所有成员组成的新数组。
##### findIndex方法
findIndex方法的用法与find方法非常类似,唯一区别是findIndex方法返回的是位置,而不是成员值。
##### findIndex方法与indexOf方法的对比
1. 不同点:findIndex方法以回调函数为参数,可以进行复杂的条件筛选,indexOf方法不接受回调函数,只接受搜索值,只有全等于,才算符合条件。 2. 相同点:都是返回index位置。
##### fill方法
fill方法是使用给定值,无脑填充一个数组,无论数组原来是什么样子,元素一律全替换成定值。 fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。
|
[‘a’, ‘b’, ‘c’].fill(7, 1, 2) // fill方法从 1 号位开始,向原数组填充 7,到 2 号位之前结束
// [‘a’, 7, ‘c’]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| ##### 新的遍历方法:entries(),keys()和values()
ES6 提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个迭代器对象,注意,这里返回的迭代器对象并不是数组。 keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。 其中,values()在chrome和Firefox中还没有实现,暂时不举例了,道理都一样。
```js let a = [1,3,5].keys(); a; // 一个迭代器对象 a.next(); // {value: 0, done: false} a.next(); // {value: 1, done: false} a.next(); // {value: 2, done: false} a.next(); // {value: undefined, done: true}
for (let index of ['a', 'b'].keys()) { console.log(index); } // 0 // 1 ``` ```js let b = [1,3,5].entries(); b; // 一个迭代器对象 b.next(); // {value: Array(2), done: false} b.next(); // {value: Array(2), done: false} b.next(); // {value: Array(2), done: false} b.next(); // {value: undefined, done: true}
for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem); } // 0 "a" // 1 "b"
|
includes方法
includes方法返回一个布尔值,表示某个数组是否包含给定的值,是ES7引入的新方法。
includes方法跟find方法、indexOf方法的区别
方法
返回值
使用回调函数
find
满足条件的第一个元素
使用
indexOf
全等条件的第一个元素的位置值
不使用
includes
如果有全等的元素,就返回true,否则返回false
不使用
所以,在流程语句中,应当优先使用includes方法。 相对于includes方法,indexOf方法有两个缺点: 一是,不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。 二是,它内部使用严格相等运算符(===)进行判断,没有任何例外,这会导致对NaN的误判。
1 2 3 4 5
| [NaN].indexOf(NaN) // -1
[NaN].includes(NaN) // true
|