Array.from()
Array.from方法用于将“类数组”对象和“可迭代”对象转为真正的数组。
类数组对象
下面这个对象就是类数组对象,只不过很罕见,它的唯一特征就是必须有length属性。同时它一般应该由类似于数组下标的键名,但不是必须。
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都可以将它们转为真正的数组。
let ps = document.querySelectorAll('p');
Array.from(ps); // 真正的数组
// arguments对象
function foo() {
var args = Array.from(arguments); // 真正的数组
// ...
}
可迭代对象
只要是部署了 Iterator 接口的数据结构,Array.from都能将其转为数组。
Array.from('hello')
// ['h', 'e', 'l', 'l', 'o']
let namesSet = new Set(['a', 'b'])
Array.from(namesSet) // ['a', 'b']
上面代码中,字符串和 Set 结构都具有 Iterator 接口,因此可以被Array.from转为真正的数组。
克隆新数组
Array.from([1, [2,3], 4])
跟扩展运算符(...)的对比
扩展运算符的介绍详见ES6的扩展运算符和剩余操作符的对比和应用。
- 相同点,都可以将部署了 Iterator 接口的数据结构转为数组。
- 不同点,
...
不能将类数组对象转化为真正数组;Array.from()可以。
妙用
Array.from()可以将字符串转为数组,然后返回字符串的长度。因为它能正确处理各种 Unicode 字符,可以避免 JavaScript 将大于\uFFFF的 Unicode 字符,算作两个字符的 bug。
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]
如果采用Array.of方法,行为就统一了。
Array.of() // []
Array.of(3) // [3]
Array.of(3, 11) // [3, 11]
Array.of(3, 11, 8) // [3, 11, 8]
copyWithin方法
copyWithin方法顾名思义是内部元素复制,就是用内部一部分元素,来替换内部另一部分元素。
.copyWithin(target, start = 0, end = this.length)
它接受三个参数。
- 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]
find方法和findIndex方法
find方法
find方法用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
find方法与filter方法的对比
find方法只返回遇到的第一个符合条件的数组成员,filter方法会返回符合条件的所有成员组成的新数组。
findIndex方法
findIndex方法的用法与find方法非常类似,唯一区别是findIndex方法返回的是位置,而不是成员值。
findIndex方法与indexOf方法的对比
- 不同点:findIndex方法以回调函数为参数,可以进行复杂的条件筛选,indexOf方法不接受回调函数,只接受搜索值,只有全等于,才算符合条件。
- 相同点:都是返回index位置。
fill方法
fill方法是使用给定值,无脑填充一个数组,无论数组原来是什么样子,元素一律全替换成定值。
fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。
['a', 'b', 'c'].fill(7, 1, 2) // fill方法从 1 号位开始,向原数组填充 7,到 2 号位之前结束
// ['a', 7, 'c']
新的遍历方法:entries(),keys()和values()
ES6 提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个迭代器对象,注意,这里返回的迭代器对象并不是数组。
keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。
其中,values()在chrome和Firefox中还没有实现,暂时不举例了,道理都一样。
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
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方法。
indexOf方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判。
[NaN].indexOf(NaN)
// -1
[NaN].includes(NaN)
// true
网友评论