ES6为数组带来了很多很实用的方法:Array.of( )、Array.from( )、find( )、findIndex( )、fill( )、entries( )、values(),此外还有一个更简洁的语法:数组推导,能让我们更方便地生成一个新数组。
Array.of()函数
- 函数作用:将一组值,转换成数组。
1
2
3
4Array.of('w','i','r')//["w", "i", "r"]返回数组
Array.of(['w','o'])//[['w','o']]返回嵌套数组
Array.of(undefined)//[undefined]依然返回数组
Array.of()//[]返回一个空数组 - Array.of()方法永远返回一个数组,参数不分类型,只分数量,数量为0返回空数组。
Array.from( )函数
- 函数作用:可以将类似数组的对象或者可遍历的对象转换成真正的数组。
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{
Array.from({'0':'w','1':'b',length:2})
//["w", "b"],返回数组的长度取决于对象中的length,故此项必须有!
Array.from({'0':'w','1':'b',length:4})
//["w", "b", undefined, undefined],数组后2项没有属性去赋值,故undefined
Array.from({'0':'w','1':'b',length:1})
//["w"],length小于key的数目,按序添加数组
}
{
let p = document.querySelectorAll('p')
let Arr = Array.from(p)
console.log(Arr)
Arr.forEach(function(item){
console.log(item.textContent)
})
}
{
Array.from('wbiokr')//["w", "b", "i", "o", "k", "r"]
//相当于map的功能(映射)
var arr = Array.from([1,3,5],function(item){
return item +2
})
console.log(arr)// [3,5,7]
} - Array.from可以把带有lenght属性类似数组的对象转换为数组,也可以把字符串等可以遍历的对象转换为数组,它接收2个参数,转换对象与回调函数
find( )函数
- 函数作用:找出数组中符合条件的第一个元素。
1
2
3
4
5let arr = [1,2,3,4,5,6];
arr.find(function(value){
return value > 2;
});
//结果:value=3 返回第一个符合条件的x值 - find()函数的参数是一个匿名函数,数组的每个元素都会进入匿名函数执行,直到结果为true,find函数就会返回value的值:3。倘若所有元素都不符合匿名函数的条件,find( )函数就会返回undefind
1
2
3
4
5
6
7
8let arr1=[4,2,3,'sdf',-2];
var b =arr1.find(function(num,index,arr){
if(x<4){
console.log(x) //2 3 -2
console.log(i) //1 2 4
console.log(arr) //[4, 2, 3, "sdf", -2]
}
}) - 回调函数默认返回值x
- find的参数为回调函数,回调函数可以接收3个参数,值num、下标index、数组arr
findIndex( )函数
- 函数作用:返回符合条件的第一个数组成员的位置。
1
2
3
4
5let arr = [7,8,9,10];
arr.findIndex(function(value){
return value > 8;
});
//结果:下标 2的 位置 - 因为数组元素中大于8的元素是9,而元素9的位置正式2,(数组元素是从0算起)。倘若所有元素都不符合匿名函数的条件,findIndex( )函数就会返回-1。
1
2
3
4
5
6let arr=[1,2,234,'sdf',-2];
arr.findIndex(function(x,i,arr){
if(x<2){console.log(x,i,arr)}
})
//结果:1 0 [1, 2, 234, "sdf", -2],-2 4 [1, 2, 234, "sdf", -2] - indIndex和find差不多,不过默认返回的是索引。
includes 寻找数组中是否有某个值
1
2console.log([1,2,NaN].includes(1))//true
console.log([1,2,NaN].includes(NaN))//truefill( )函数
- 函数作用:用指定的值,填充到数组。
1
2
3let arr = [1,2,3];
arr.fill(4);
//结果:[4,4,4] - 如果我想只填充部分元素,fill( )函数提供了一些参数,用于指定填充的起始位置和结束位置。
1
2
3let arr = [0,1,2,3];
arr.fill(4,1,3);
//结果:[0,4,4,3] - 上面的代码中第2个参数和第3个参数的意思是起始位置
- 从位置1的元素开始填充数字4,截止到位置3之前,所以是位置1、2的元素被4填充了,结果:[0,4,4.3]
跟遍历相关联的三个元素 entries 、keys 、values
entries( )函数
- 对数组的键值对进行遍历,返回一个遍历器,可以用for..of对其进行遍历。
1
2
3
4
5
6
7
8
9
10let arr=['w','l'];
for(let a of arr.entries()){
console.log(a)
}//结果:[0,'w'],[1,'l']
for(let [i,v] of ['w', 'l'].entries()){
console.log(i,v);
}
//0 "w"
//1 "l" - 我们将entries( )函数返回的一个遍历器,用for…of进行遍历,能得到数组的键值:0和1,以及对应的数组元素:‘a‘和’b‘。
- 如果只想遍历数组的索引键的话,可以使用另一个实例方法。
keys( )函数
- 函数作用:keys,对数组索引的遍历
1
2
3
4
5for(let index of ['w', 'l'].keys()) {
console.log(index);
}
//0
//1values( )函数
- 作用:对数组的元素进行遍历
1
2
3
4
5let arr=[1,2,234,'sdf',-2];
for(let a of arr.values()){
console.log(a)
}
//结果:1,2,234,sdf,-2 遍历了数组arr的值数组推导
- 数组推导是非标准的
- 数组推导是非标准的。考虑到以后,应该使用 Array.prototype.map, Array.prototype.filter, 和 arrow functions.
扩展运算符
- 扩展运算符(spread)是三个点(…)。它好比 rest 参数的逆运算
- 将一个数组转为用逗号分隔的参数序列。
1
2
3
4
5
6
7
8console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
console.log( [...document.querySelectorAll('div')])
// [<div>, <div>, <div>] - 该运算符主要用于函数调用
1
2
3
4
5
6function add(a , b){
return a + b
}
const number = [10,12]
console.log(add(...number))
//22 - 扩展运算符与正常的函数参数可以结合使用,非常灵活。
1
2
3
4
5
6
7function f(v, w, x, y, z) {
return [v, w, x, y, z]
}
const args = [0, 1];
console.log(f(-1, ...args, 2, ...[3]))
//[-1, 0, 1, 2, 3] - 扩展运算符后面还可以放置表达式。
1
2
3
4
5
6let x = -1
const arr = [
...(x > 0 ? ['a'] : []),'b',
];
console.log(arr)
//[b]1
2
3
4
5
6let x = 1
const arr = [
...(x > 0 ? ['a'] : []),'b',
];
console.log(arr)
//["a", "b"] - 如果扩展运算符后面是一个空数组,则不产生任何效果。
1
2[...[], 1]
// [1] - 替代函数的 apply 方法
- 由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。
1
2
3
4
5
6
7
8
9
10
11
12
13// ES5 的写法
function f(x, y, z) {
// ...
}
var args = [0, 1, 2];
f.apply(null, args);
// ES6的写法
function f(x, y, z) {
// ...
}
let args = [0, 1, 2];
f(...args);下面是扩展运算符取代apply方法的一个实际的例子,应用Math.max方法,简化求出一个数组最大元素的写法。
1 | // ES5 的写法 |
-上面代码中,由于 JavaScript 不提供求数组最大元素的函数,所以只能套用Math.max函数,将数组转为一个参数序列,然后求最大值。有了扩展运算符以后,就可以直接用Math.max了。
扩展运算符的应用
(1)复制数组
1 | const a1 = [1, 2]; |
- a2并不是a1的克隆,而是指向同一份数据的另一个指针。修改a2,会直接导致a1的变化。
- ES5 只能用变通方法来复制数组。
1
2
3
4
5const a1 = [1, 2];
const a2 = a1.concat();
a2[0] = 2;
a1 // [1, 2] - a1会返回原数组的克隆,再修改a2就不会对a1产生影响。
- 扩展运算符提供了复制数组的简便写法。(2)合并数组
1
2
3
4
5const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1; - 扩展运算符提供了数组合并的新写法。(3)与解构赋值结合
1
2
3
4
5
6
7
8
9
10
11
12// ES5
var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e'];
// ES5的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]1
2
3
4
5
6
7
8
9
10
11const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first) // 1
console.log(rest) // [2, 3, 4, 5]
const [first, ...rest] = [];
console.log(first) // undefined
console.log(rest) // []
const [first, ...rest] = ["foo"];
console.log(first) // "foo"
console.log(rest) // []扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。
(4)字符串1
2
3
4
5const [...butLast, last] = [1, 2, 3, 4, 5];
// 报错
const [first, ...middle, last] = [1, 2, 3, 4, 5];
// 报错能够正确识别四个字节的 Unicode 字符。1
2[...'hello']
// [ "h", "e", "l", "l", "o" ]1
2
3
4
5
6
7
8'x\uD83D\uDE80y'.length // 4
[...'x\uD83D\uDE80y'].length // 3
function length(str) {
return [...str].length;
}
length('x\uD83D\uDE80y') // 3 - 凡是涉及到操作四个字节的 Unicode 字符的函数,都有这个问题。因此,最好都用扩展运算符改写。