ES6语法快速入门(4)| 青训营笔记

85 阅读6分钟

这是我参与「第四届青训营 」笔记创作活动的的第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新增的数据结构SetMap

下面是一个类似于数组的对象, 通过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 
// 1for(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的误判。