ES6-数组的扩展

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的扩展运算符和剩余操作符的对比和应用。

  1. 相同点,都可以将部署了 Iterator 接口的数据结构转为数组。
  2. 不同点,...不能将类数组对象转化为真正数组;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
  • 版权声明: 本博客所有文章,未经许可,任何单位及个人不得做营利性使用!转载请标明出处!如有侵权请联系作者。
  • Copyrights © 2015-2023 翟天野

请我喝杯咖啡吧~