往期内容
1.扩展运算符
扩展运算符(spread)是三个点 (...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。
console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
[...document.getElementsByClassName('tag')]
// [<div>, <div>, <div>]
扩展运算符与正常的函数参数可以结合使用,非常灵活。
function test(v, w, x, y, z) { }
const args = [0, 1];
test(-1, ...args, 2, ...[3]);
扩展运算符后面还可以放置表达式。
const arr = [
...(2 > 0 ? ['a'] : []),
'b',
];
// ['a', 'b']
如果扩展运算符后面是一个空数组,则不产生任何效果。
[...[], 1]
// [1]
2.替代函数的 apply 方法
由于扩展运算符可以展开数组,所以不再要apply方法,将数组转为函数的参数了。
// ES5 的写法
function test(x, y, z) {
// ...
}
var args = [0, 1, 2];
test.apply(null, args);
// ES6的写法
function test1(x, y, z) {
// ...
}
let args1 = [0, 1, 2];
test1(...args);
3.扩展运算符的应用
3.1 复制数组
数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。
const array = [1, 2];
const array1 = array;
array1[0] = 2;
consloe.log(array1) // [2, 2]
上面代码中, array1 并不是array的克隆,而是指向同一份数据的另一个指针。修改array1,会直接导致array的变化。
ES5 只能用变通方法来复制数组。
const array = [1, 2];
const array1 = array.concat();
array1[0] = 2;
console.log(array) // [1, 2]
上面代码中,array 会返回原数组的克隆,再修改 array1 就不会对 array 产生影响。
扩展运算符提供了非常常用并且简单的复制数组的简便写法。
const array = [1, 2];
// 写法一
const array1 = [...array];
// 写法二
const [...array1] = array;
上面的两种写法,都是扩展运算符的简单写法,非常的实用
3.2 合并数组
扩展运算符提供了数组合并的新写法。
大家可以想一下,没有ES5的时候,合并数组是怎么搞的,不过哪些都不重要了,人往高处走。
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
不过,这两种方法都是浅拷贝,使用的时候需要注意。
const array1 = [{ foo: 1 }];
const array2 = [{ bar: 2 }];
const array3 = array1.concat(array2);
const array4 = [...array1, ...array2];
array3[0] === array1[0] // true
array4[0] === array2[0] // true
上面代码中,array3和array4是用两种不同方法合并而成的新数组,但是它们的成员都是对原数组成员的引用,这就是浅拷贝。如果修改了原数组的成员,会同步反映到新数组。
3.3 与解构赋值结合
扩展运算符可以与解构赋值结合起来,用于生成数组。
const [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) // []
3.4 字符串
扩展运算符还可以将字符串转为真正的数组。
[...'hello']
// [ "h", "e", "l", "l", "o" ]
3.5Map 和 Set 结构
扩展运算符内部调用的是数据结构的 Iterator 接口,因此只要具有 Iterator 接口的对象,都可以使用扩展运算符,比如 Map 结构。
let map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
let arr = [...map.keys()]; // [1, 2, 3]
4.Array.from()
Array.from()方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
下面是一个类似数组的对象,Array.from()将它转为真正的数组。
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
实际应用中,常见的类似数组的对象是 DOM 操作返回的 NodeList 集合。
// NodeList对象
let ps = document.querySelectorAll('p');
Array.from(ps).filter(p => {
return p.textContent.length > 100;
});
Array.from('hello')
// ['h', 'e', 'l', 'l', 'o']
let namesSet = new Set(['a', 'b'])
Array.from(namesSet) // ['a', 'b']
如果参数是一个真正的数组,Array.from()会返回一个一模一样的新数组。
Array.from([1, 2, 3])
// [1, 2, 3]
值得提醒的是,扩展运算符(...)也可以将某些数据结构转为数组。
// arguments对象
function foo() {
const args = [...arguments];
}
// NodeList对象
[...document.querySelectorAll('div')]
5.Array.of()
Array.of()方法用于将一组值,转换为数组。
Array.of(3, 11, "8") // console.log([3,11,"8"])
Array.of(3) // console.log([3])
Array.of(3).length //console.log(1)
6.数组实例的 find() 和 findIndex()
数组的find方法,用于找出第一个符合条件的数组成员。参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,并且返回该成员。如果没有符合条件的成员,则返回undefined。
console.log([1, 4, -5, 10].find((i) => i === 4))
其实find是一个回调函数
[8, 9, 10, 5].find(function(value, index, arr) {
return value > 9;
}) // 10
当前方法的回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。
其实findIndex方法与find方法挺相似的返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,返回-1.
7.数组实例的 fill()
fill()方法使用给定值,填充一个数组,你可以简单的理解fill() 是个站坑的
['a', 'b', 'c'].fill(3)
// [3,3,3]
new Array(3).fill(5)
// [5,5,5]
上面操作显示该方法用于空数组的初始化占坑非常方便。数组中已有的数据,会被全部抹去。
方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置
[1, 2, 2, 3].fill(6, 1, 3);
//[1,6,63]
8.数组实例的 includes()
includes()方法返回一个布尔值,表示某个数组是否包含给定的值
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3)则会重置为从0开始。
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
9.数组实例的 flat()、sort()
数组的成员有时还是嵌套数组,flat()用于将嵌套的数组解构,变成普通数组。该方法返回一个新数组,对原数据没有影响。
[1, 2, [3, 4,5,6,7,8]].flat() // [1, 2, 3, 4, 5, 6, 7, 8]
上面代码中,原数组的成员里面有一个数组,flat()方法将子数组的成员取出来,添加在原来的位置。
sort() 排序大家应该都不陌生吧。
[10, 2, 12, 4, 5, 10, 78, 5, 5, 55, 96, 2].sort((a,b)=>{ return a>b?1:-1})
// [2, 2, 4, 5, 5, 5, 10, 10, 12, 55, 78, 96]
[10, 2, 12, 4, 5, 10, 78, 5, 5, 55, 96, 2].sort((a,b)=>{ return a<b?1:-1})
// [96, 78, 55, 12, 10, 10, 5, 5, 5, 4, 2, 2]
下面是我的公众号大家一起写文章呀。