三个点...
扩展运算符可以将一个数组转为用逗号分隔的参数序列。
此时你有没有想起rest参数,rest参数是将参数序列转为一个数组。所以说,扩展运算符是rest参数的逆运算。
关于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的实际应用:
// 比较一组数中的最大值,max方法接收以逗号隔开的参数序列而不是数组
Math.max(1, 2, 3)
// 但在一般情况下,都需要去比较出一个数组中所有数据的最大值
Math.max.apply(null, [1, 2, 3])
Math.max(...[1, 2, 3])
将一个数组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写法
// 将数组arr合并到[1, 2]
[1, 2].concat(arr) // ES5写法
[1, 2, ...arr] // ES6写法
// 将数组arr2合并到arr1
arr1.concat(arr2) // ES5写法
[...arr1, ...arr2] // ES6写法
与结构赋值结合
函数的返回值:js的函数只能返回一个值,如果需要返回多个值只能返回数组或对象,但扩展运算符提供了解决这个问题的变通方法。
var dateFields = readDateFields(database);
var d = new Date(...readDateFields)
// 这段代码从数据库取出一行数据,通过扩展运算符,直接将其传入构造函数Date
// 这个例子实质上函数的返回值还是一个数组,只是利用扩展运算符将其展开成为用逗号隔开的参数序列
将字符串转为真正的数组,且能够正确识别32位的Unicode字符(此处未做解释说明)
var str = 'hello';
console.log(...str) //['h', 'e', 'l', 'l', 'o']
任何实现了Iterator接口的对象都可以用扩展运算符转为真正的数组(解释说明待补充)
扩展运算符内部调用的的是数据结构的Iterator接口,因此只要具有Iterator接口的对象都可以使用扩展运算符,如Map结构,Set结构,Generator函数(解释说明待补充)
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写法
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()总是返回参数值组成的数组。如果没有参数,就返回一个空数组。
数组实例的copyWithin()方法,在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。
Array.prototype.copyWithin(target, start = 0, end = this.length)
它接受三个参数。
这三个参数都应该是数值,如果不是,会自动转为数值。
[1, 2, 3, 4, 5].copyWithin(0, 3)
// [4, 5, 3, 4, 5]
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
fill
方法使用给定值,填充一个数组。
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
上面代码表明,fill
方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。
fill
方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。
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"
}
Array.prototype.includes
方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes
方法类似。ES2016 引入了该方法。可以识别NaN了。
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true