这是我参与「第四届青训营 」笔记创作活动的的第7天
ES6 快速入门(4)
数组的扩展
扩展运算符
扩展运算符号是三个点(...), 意义是将一个数组转换为用逗号分隔的参数序列。
代码示例:
const a = [1,2,3];
console.log(...a);
// 1 2 3
console.log(1, ...a , 5)
// 1 2 3 4 5
该运算符主要用于函数调用的参数为多个参数,可以使用数组展开代替 和 数组展开赋值
// 将一个数组内部的元素 push 到另一个元素内
let arr = [1,2,3]
let items = [4,5,6,7]
// 利用push
function push(arr, ...items){
arr.push(...items);
}
arr = [...arr, ...items]
如果扩展运算符后面是一个空数组,则不产生任何效果
代替数组的apply 方法
由于扩展运算符可以展开数组, 所以不再需要使用apply 方法将数组转换为函数参数。
call() 方法指分别接受参数。
apply() 方法指接受数组形式的参数。
举例说明:
// ES5 的写法
function f(x, y, z){
// ...
}
var args = [0, 1, 2];
f.apply(null, args);
// ES6 的写法
function f(x, y, z){
// ...
}
var args = [0,1,2];
f(...args);
下面是扩展运算符取代 apply 方法的一个实际例子; 应用math.max 方法来简化求出一个数组中的最大元素。
// ES5 的写法
Math.max.apply(null, [14, 3, 77])
// ES6 的写法
Math.max(...[14, 3, 77])
// 等同于
Math,max(14, 3, 77)
上面的代码中,由于js 不提供求数组最大元素的函数,所以只能使用math.max 函数将数组转换为一个参数 序列,然后求最大值。
扩展运算符的应用
合并数组
扩展运算符 为我们提供了数组合并的新的写法
// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]
与解构赋值结合
扩展运算符可以与解构赋值结合起来,用于生成数组。
// 取数组首项 和 从第二项之后的每一项
// ES5
a = list[0];
rest = list.slice(1)
// ES6
[a, ...rest] = list
如果 将扩展运算符 用于数组赋值,则只能将其放在参数的最后一位,否则会报错。
const [...butLast, last] = [1, 2, 3, 4, 5];
// 报错
const [first, ...middle, last] = [1,2,3,4,5];
// 报错
字符串
扩展运算符可以将 字符串转换为真正的数组
[...'hello']
// ['h', 'e', 'l', 'l', 'o']
Array.from() 方法
array.from() 方法用于将两类对象转为 真正的数组,类似与数组的对象和可遍历的对象(包括ES6新增的数据结构Set 和 Map)
下面是一个类似于数组的对象, 通过Array. from () 方法将其转化为真正的数组。
let arrays = {
'0': 'a',
'1': 'b',
length : 2
};
// ES5 的写法
var arr1 = [].slice.call(arrays); // ['a', 'b']
// ES6 写法
var arr2 = Array.from(arrays);
实际 应用中,常见的类似数组的对象是DOM操作返回的NodeList 集合,以及函数内部的arguments对象。Array.from 都可以将这些转换为真正的数组。
举例说明:
// NodeList 对象
let divs = document.querySelectorAll('div');
Array.from(divs).forEach(div => console.log(div);)
// arguments 对象
function foo(){
var args = Array.from(arguments);
}
上面的第一段代码中,forEach 只有真正的数组才可以使用foreach 遍历
所以只要是部署了Iterator 接口的数据结构,Array.from 都能将其转为数组。
Array.of() 方法
Array.of() 方法 用于将一组值转换为 数组。
Array.of(3, 11, 8); // [3, 11, 8]
Array.of(3); // [3]
这个方法的主要目的是弥补数组的构造函数Array()的不足,因为参数个数的不同会导致Array()的行为有差异。
Array(); // []
Array(3); // [, , , ]
Array(3, 11, 8); // [3,11, 8]
上面的代码中,Array方法没有参数,有1个参数或者有3个参数返回结果都不统一,返回结果只有当参数个数不少于2个时,Array()方法才会返回参数组成的新数组。参乎上个数只有1个时,实际上是指定的数组长度。
Array.of() 基本可以用来代替Array ( ) 或者new Array( ) ,并且不存在由于参数不同而导致的重载。它的行为非常统一。
Array.of () 总是返回参数值组成的数组, 如果没有参数,就返回一个空数组。
function ArrayOf(){
return [].slice.call(arguments);
}
数组实例的find 和 findIndex 方法
数组实例的find 方法用于找出 第一个符合条件的数组成员。 它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找到第一个返回值为true 的成员,然后返回该成员,如果没有符合条件的成员,则返回 undefined
// 找到第一个 大于100的成员
[1, 4, 199, -1].find(n => n > 100);
// 199
上面的代码中,find 方法的回调函数可以接受 3 个参数, 依次是 当前值,当前位置, 原数组
数组实例的findIndex 方法的用法与这个类似,返回第一个符合条件成员的位置,如果所有成员都不符合条件,则返回 -1
[1, 5, 10, 15].findIndex(function(value, index, arr){
return value > 9;
})
// 2
这两个方法都可以发现NaN,弥补了数组的IndexOf 方法的不足
indexOf 方法无法识别数组的NaN 成员,但是findIndex 方法可以借助Object.is 来做到
数组实例的fill()
fill 方法使用给定值填充一个数组
['a', 'b', 'c'].fill(7)
// ['7', '7', '7']
fill 方法用于空数组的初始化时非常方便,数组中已有的元素会被全部抹去。
fill 方法还可以接受第二个和第三个参数, 用于指定填充的起始位置和结束位置
数组实例的entries(), keys()和 values()
ES6 提供了3个新方法, entries() ,keys() ,values() ---用于遍历数组,它们都返回一个遍历器对象,可用for ..... of 循环遍历,唯一的区别是 keys 是对键名的遍历, values 是对键值的遍历,entries是对键值对的遍历
使用方式:
for(let index of ['a', 'b'].keys()){
console.log(index);
}
// 0
// 1
for(let item of ['a', 'b'].values()){
console.log(item);
}
// 'a'
// 'b'
for(let [index, item] of ['a', 'b'].entries()){
console.log(index, item)
}
// 0 'a'
// 1 'b'
数组实例的includes ()
Array.prototype.includes 方法返回一个布尔值,表示某个数组是否包含所给定的元素,与字符串的include 方法类似。ES2016 引入了该方法。
在没有该方法前,我们一般使用indexOf 方法来检查是否包含某个值。
// ES2016 之前
if(arr.indexOf(x) !== -1){
// ...
}
// includes
if(arr.includes(x)){
// ...
}
indexOf 方法有两个缺点: ① 不够语义化,其含义是找到参数值的第一个出现位置,所以要比较是否不等于-1。
② 其内部使用严格相等运算符(===) 进行判断,会导致NaN的误判。