数组扩展
扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。
扩展运算符后面还有可以跟其他表达式
let arr = [... 1>2? ['No'] : ['Yes'],'b'];
console.log(...arr); // Yes b
如果扩展运算符后面是一个空数组,则不产生任何效果
[...[], 1]
// [1]
//扩展运算符与apply
{
let args = [23,45,14,56,4];
let args1 = [4,2,8,6];
//es5
Math.max.apply(null,args);
Array.prototype.push.apply(args1,args);
//es6
Math.max(...args);
args1.push(...args);
}
扩展运算符的应用
合并数组,解构赋值结合
let foo = [1,2,3];
let baz = ['bmw','benzi','audi'];
let target = [];
//es5
target.concat(foo,baz);
let first = baz[0];
let others = baz.slice(1);
//es6
target = [...foo,...baz];
{
let first ,others;
([first,...others] = baz);
console.log(first); // 'bmw'
console.log(others); // ['benzi','audi']
}
如果将扩展运算符用作数组赋值,则只能放在参数最后一位
const [...butLast, last] = [1, 2, 3, 4, 5];
// 报错
const [first, ...middle, last] = [1, 2, 3, 4, 5];
// 报错
将字符串分割成数组
[...'benzi'];
// ['b','e','n','z','i'];
// 等价于
Array.from('benzi');
面的写法,有一个重要的好处,那就是 能够正确识别32位的Unicode字符
'x\uD83D\uDE80y'.length // 4
[...'x\uD83D\uDE80y'].length // 3
**JavaScript会将32位Unicode字符,识别为2个字符,采用扩展运算符就没有这个问题 **
凡是涉及到 **操作32位 Unicode 字符的函数 **,都有这个问题。因此,最好都用扩展运算符改写。
let str = 'x\uD83D\uDE80y';
str.split('').reverse().join('')
// 'y\uDE80\uD83Dx'
[...str].reverse().join('')
// 'y\uD83D\uDE80x'
ps:Array.from也可与实现扩展运算符的以上功能
如果不用扩展运算符,字符串的reverse操作就不正确。
扩展运算符可以将实现了 Iterator 接口的对象转换为数组
[...document.querySelectorAll('div')];
ps: Array.from方法将arrayLike转为真正的数组
Map 和 Set 结构,Generator 函数
扩展运算符可以将以上数据结构或者函数转换为数组,因为这些数据结构都实现了Iterator接口
var go = function*(){
yield 1;
yield 2;
yield 3;
};
[...go()] // [1, 2, 3]
Array.from()
Array.from方法用于将 两类对象转为真正的数组: 类似数组的对象(array-like object)和 可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)
let arrlike = {
0: 'bmw',
1: 'benzi',
2: 'audi',
length: 3
};
console.log(Array.from(arrlike)); // [ 'bmw', 'benzi', 'audi' ]
// NodeList对象
let ps = document.querySelectorAll('p');
Array.from(ps).forEach(function (p) {
console.log(p);
});
// arguments对象
function foo() {
var args = Array.from(arguments);
// ...
}
如果参数是一个真正的数组,Array.from会返回一个一模一样的 新数组。
let a = [1, 2, 3];
// undefined
let b = Array.from(a);
// undefined
a==b;
// false
a === b
// false
a[3] = 4;
// 4
a
// (4) [1, 2, 3, 4]
b
// (3) [1, 2, 3]
任何有 __length属性__的对象,都可以通过Array.from方法转为数组,而此时 扩展运算符就无法转换。
let arr0 =Array.from({length:3});
console.log(arr0); // [ undefined, undefined, undefined ]
let a = {0:'a',b:'b',2:'c',length:4}
Array.from(a); // (4) ["a", undefined, "c", undefined]
Array.from还可以接受 第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);
let arr0 =Array.from({length:3},x=>x || 3);
console.log(arr0); // [ 3, 3, 3 ]
还可以传入Array.from的第三个参数,用来绑定this。
Array.of()
Array.of方法用于将一组值,转换为数组。
Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1
该方法是弥补数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的行为有差异。
Array.of基本上可以用来替代Array()或new Array(),并且不存在由于参数不同而导致的重载。它的行为非常统一。
Array.of() // []
Array.of(undefined) // [undefined]
Array.of(1) // [1]
Array.of(1, 2) // [1, 2]
Array.of总是 返回参数值组成的数组。如果没有参数,就返回一个空数组
数组实例的 find() 和 findIndex()
find方法,用于找出 第一个符合条件 的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
[1,2,3,4].find((n)=>n>2);
//3
[1,2,3,4].findIndex((n)=>n>2);
//2
findIndex()方法返回的是第一个满足条件的 元素索引,如果没有找到返回-1
find,findIndex方法的 回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。这两个方法都可以接受 第二个参数,用来绑定回调函数的this对象。
ps: 另外,这两个方法都可以发现NaN,弥补了数组的IndexOf方法的不足。
[NaN].indexOf(NaN)
// -1
[1,3,NaN].find(x => Object.is(NaN,x)); //NaN
fill()方法
fill方法使用给定值,填充一个数组。如果数组有原始值,填充的值会覆盖掉数组原来的值,该方法接受三个参数,第一个参数是填充数组的值,第二个,第三个参数分别是填充的开始位置(包含)和填充结束位置(不包含)。若后面两个参数缺省,则会填充整个数组。
['a', 'b', 'c'].fill(7, 1, 2) ; // ['a',7,'b']
includes()
表示某个数组是否包含给定的值
[1, 2, NaN].includes(NaN) // true
该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
另外,Map 和 Set 数据结构有一个has方法,需要注意与includes区分。
数组空位
ES5中的部分数组的方法都会忽略空位, ES6 则是明确将空位转为undefined。
Array.from方法,扩展运算符会将数组的空位,转为undefined,也就是说,这个方法不会忽略空位。
Array.from(['a',,'b'])
// [ "a", undefined, "b" ]
[...['a',,'b']]
// [ "a", undefined, "b" ]
copyWithin()会连空位一起拷贝。
[,'a','b',,].copyWithin(2,0) // [,"a",,"a"]
fill()会将空位视为正常的数组位置
new Array(3).fill('a') // ["a","a","a"]
for...of循环也会遍历空位。
entries()、keys()、values()、find()和findIndex()会将空位处理成undefined。

浙公网安备 33010602011771号