ES6数组的扩展

1 扩展运算符

1.1 写法

三个点...

1.2 作用

扩展运算符可以将一个数组转为用逗号分隔的参数序列。 

 此时你有没有想起rest参数,rest参数是将参数序列转为一个数组。所以说,扩展运算符是rest参数的逆运算。

1.3 解决了什么实际问题

1.3.1 替代了数组的apply方法

  关于apply的回顾:函数默认都会有一个apply方法,这个方法用来指定函数的执行环境,即指定this值。apply方法接收两个参数。

Function.apply(obj, args)
// obj 将作为Function类中的this对象  如果为null说明我不需要有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就可以
// args 为数组,作为Function的实参

函数的参数集合不接收数组类型的,所以如果是一个参数集合的话,可以使用apply方法来实现将数组集合传入函数。

而扩展运算符的出现使得我们不用再使用apply方法来到达这种效果,因为扩展运算符可以将一个数组转化为用逗号分隔的参数序列,所以直接使用扩展运算符就可以将一组参数集合传入函数。

var args = [1,2,3]
function add(x, y, z) {
  console.log(x + y + z)  // 6
}
add.apply(null, args)   // ES5写法
add(...args)    // ES5写法

下面是一些扩展运算符代替apply的实际应用:

  1. 求一组数的最大值
    // 比较一组数中的最大值,max方法接收以逗号隔开的参数序列而不是数组
    Math.max(1, 2, 3)
    // 但在一般情况下,都需要去比较出一个数组中所有数据的最大值
    Math.max.apply(null, [1, 2, 3])
    Math.max(...[1, 2, 3])

     

  2. 将一个数组push到另一个数组的尾部

    // push方法接收以逗号相隔的参数序列
    arr1.push(a, b, c)  // 将a, b, c依次插入arr1的尾部
    
    // 如果需要将一个数组追加到另一个数组的尾部
    Array.prototype.push.apply(arr1, [a, b, c])   // ES5写法
    arr1.push(...[a, b, c])    // ES6写法

     

1.3.2 扩展运算符的应用 

  1. 合并数组
    // 将数组arr合并到[1, 2]
    [1, 2].concat(arr)   // ES5写法
    [1, 2, ...arr]  // ES6写法
    
    
    // 将数组arr2合并到arr1
    arr1.concat(arr2)   // ES5写法
    [...arr1, ...arr2]  // ES6写法

     

  2. 与结构赋值结合

  3. 函数的返回值:js的函数只能返回一个值,如果需要返回多个值只能返回数组或对象,但扩展运算符提供了解决这个问题的变通方法。

    var dateFields = readDateFields(database);
    var d = new Date(...readDateFields)
    // 这段代码从数据库取出一行数据,通过扩展运算符,直接将其传入构造函数Date
    // 这个例子实质上函数的返回值还是一个数组,只是利用扩展运算符将其展开成为用逗号隔开的参数序列

     

  4.  将字符串转为真正的数组,且能够正确识别32位的Unicode字符(此处未做解释说明)

    var str = 'hello';
    console.log(...str)   //['h', 'e', 'l', 'l', 'o']

     

  5. 任何实现了Iterator接口的对象都可以用扩展运算符转为真正的数组(解释说明待补充)

  6. 扩展运算符内部调用的的是数据结构的Iterator接口,因此只要具有Iterator接口的对象都可以使用扩展运算符,如Map结构,Set结构,Generator函数(解释说明待补充)

2 ES6补充的一些数组方法

2.1 Array.from()

Array.from()方法用于将两类对象转为真正的数组:类数组对象和可遍历(iterable)对象。

// 下面是一个类数组对象
let arrLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};
Array.prototype.slice.call(arrLike);    // ['a', 'b' ,'c']   ES5写法
Array.from(arrLike)  // ['a', 'b' ,'c']   ES6写法

2.2 Array.of()

Array.of()方法用于将一组值转换为数组

Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1

这个方法的主要目的,是弥补数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的行为有差异。

Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]

 

上面代码中,Array方法没有参数、一个参数、三个参数时,返回结果都不一样。只有当参数个数不少于 2 个时,Array()才会返回由参数组成的新数组。参数个数只有一个时,实际上是指定数组的长度。

Array.of()基本上可以用来替代Array()或new Array(),并且不存在由于参数不同而导致的重载。它的行为非常统一。

Array.of()总是返回参数值组成的数组。如果没有参数,就返回一个空数组。

2.3 数组实例的copyWithin()

数组实例的copyWithin()方法,在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。

Array.prototype.copyWithin(target, start = 0, end = this.length)

它接受三个参数。

  • target(必需):从该位置开始替换数据。如果为负值,表示倒数。
  • start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。
  • end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。

这三个参数都应该是数值,如果不是,会自动转为数值。

[1, 2, 3, 4, 5].copyWithin(0, 3)
// [4, 5, 3, 4, 5]

2.4 数组实例的find()和findIndex()

1.数组实例的find()方法,用于返回第一个满足条件的数组成员,它的第一个参数是一个回调函数,所有数组成员依次执行该回调函数,直到有一个数组成员在执行回调函数时返回true时停止,然后返回该数组成员。如果整个数组成员都没有找到回调函数返回true的,那就返回undefined。

var arr = [1, 2, -3, -4, 5]
arr.find(item => { item < 0})   // -3

数组实例的findIndex()方法,与find()方法类似,只不过它是用于返回第一个满足条件的数组成员在数组中的索引值。

var arr = [1, 2, -3, -4, 5]
arr.find(item => { item < 0})   // 2

2.这两个方法都可以接受第二个参数,用来绑定回调函数的this对象。

function f(z) {
  return z > this.age
}
var obj = {name: 'Joy', age: 23}
[1, 3, 22, 25, 23, 27, 8].find(f ,obj)    // 25

 上面的代码中,为find设定了第二个参数obj,表示回调函数f中的this指向obj。

3.另外,这两个方法都可以用来发现NaN,弥补了数组indexOf方法的不足。

// 因为NaN不等于NaN,所以在用indexOf识别NaN时无法成功
[NaN].indexOf(NaN)    // -1

[NaN].findIndex(y => Object.is(NaN, y))    // 0
// Object.is(value1, value2)用来判断两个值是否是相同的值,如果两个值都是NaN的话,它会返回true

2.5 数组实例的fill()

fill方法使用给定值,填充一个数组。

['a', 'b', 'c'].fill(7)
// [7, 7, 7]

new Array(3).fill(7)
// [7, 7, 7]

上面代码表明,fill方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。

fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。

2.6 数组实例的entries()、keys()和values()

ES6 提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器对象,可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

var arr = ['a', 'b']
for (let index of arr.keys()) {
    console.log(index)     // 0 1
}

for (let ele of arr.values()) {
    console.log(ele)     // 'a' 'b' 
}

for (let [index, ele] of arr.entries()) {
    console.log(index, ele)    // 0 "a"     1 "b"
}

2.7 数组实例的includes()

Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。ES2016 引入了该方法。可以识别NaN了。

[1, 2, 3].includes(2)     // true
[1, 2, 3].includes(4)     // false
[1, 2, NaN].includes(NaN) // true

 

你可能感兴趣的:(ES6,前端)