1,扩展运算符
2,Array.from()
3,Array.of()
4,数组实例的 copyWithin()
5,数组实例的 find() 和 findIndex()
6,数组实例的 fill()
7,数组实例的 entries(),keys() 和 values()
8,数组实例的 includes()
9,数组实例的 flat() ,flatMap()
10,数组的空位
1,扩展运算符
含义
扩展运算符(spread)是三个点 (...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。
console.log(...[1,2,3]);
// 1 2 3
[...document.querySelectorAll('div')]
// [<div>,<div>,<div>]
如果 扩展符后面跟的是一个空数组,那么则不产生任何效果
[...[],1]
// [1]
注意,如果在括号中使用 扩展运算符 ,那么JavaScript 引擎会认为这是在 函数中调用 扩展运算符,如果这时不是函数调用,就会报错。
(...[1,2,3])
// Uncaught SyntaxError: Unexpected number
console.log(...[1,2,3])
// 不会报错
console.log((...[1,2,3]))
// 会报错 Uncaught SyntaxError: Unexpected number
扩展运算符的应用:
1,复制数组
2,合并数组
3,与解构赋值结合
4,把字符串转换为真正的数组
5,实现了 Iterator 接口的对象
const a1 = [1,2,3];
const a2 = [...a1];
// 这时修改 a2 的值不会改变 a1 的值
const a3 = [...a1,...a2];
// [1,2,3,1,2,3]
const [a4,...a5] = [a3];
// a4 = 1
// a5 = [2,3,1,2,3]
// 解构赋值时 扩展符必须放到最后,不然会报错
[...'hello']
// ['h','e','l','l','o']
[...document.querySelectorAll('div')]
// [<div>,<div>,<div>]
// 任何定义了 遍历器(Iterator)接口的对象,都可以用扩展运算符转为真正的数组
2,Array.from()
Array.from 方法用于将两类对象转为真正的数组:
1,类似数组的对象(array like object)
2,可遍历的对象(set ,map)
下面试一个类似数组的对象, Array.from 将它转为真正的数组
// 类似数组的对象
let likeArray = {
'0': 'a',
'1': 'b',
'2': 'c',
'length': 3
}
let arr = Array.from(likeArray); // ['a','b','c']
实际应用中:Dom 操作返回的 NodeList 集合,函数内部 arguments 对象
let ArrayLike = document.querySelectorAll('div');
let arr = Array.from(ArrayLike);
function foo() {
var args = Array.from(arguments);
}
Array.from 还可以接受第二个参数,作用类似于数组的map 方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
Array.from(arrayLike, x=>x*x);
// 等同于
Array.from(arrayLike).map(x=>x*x);
Array.from([1,2,3],(x) => x * x);
// [1,4,9]
3,Array.of()
Array.of 方法用于将一组数值,转换为数组
Array.of(3,11,8) // [3,11,8]
基本上 Array.of 可以代替 Array() 生成数组,因为 Array.of() 的行为非常统一
Array.of() // []
Array.of(undefined) // [undefined]
Array.of(1,2,3) // [1,2,3]
Array.of(3) // [3]
Array(3) // [,,] 这里的 3 指的是数组的长度,所以推荐使用 Array.of()
4,数组实例的 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]
上面这个代码表示:target=0,start =3,end 默认等于数组长度 5,也就是说从数组第三位开始读取,到 第5位停止,不读取第5位,也就是读取第3,4位的数据 也就是说 读取的数据为 4,5 ,而 target = 0 ,则表示从数组的第 0 位开始替换,这时 4,5 代替了原来的 1,2 ,所以这个数组最终变成了[4,5,3,4,5]
数组实例的 find() 和 findIndex()
find()
find() 方法用于找出第一个符合条件的数组成员,并返回这个数组成员。它的参数是一个回调函数,所有的数组成员依次去 执行这个回调函数,直到找到第一个返回值为 true 的成员,然后返回该成员,如果没有符合条件的成员,则返回 undefined。
[0,0,0,1].find((n) => n != 0)
// 1
上面代码找出第一个不为 0 的数组成员
[1,2,3,4].find(function(value,index,arr){
return value > 2;
}) // 3 (找出大于 2 的数组成员)
find() 的回调函数可以接受三个参数,依次是数组成员 value, 该成员的索引 index, 以及原数组 arr(这里value,index可以写成其他值)。
findIndex()
数组实例的 findIndex() 方法与 find() 方法非常类似,只不过 findIndex() 返回的是第一个符合条件的数组成员的位置,如果没有符合条件的数组成员,则返回 -1。
[1,2,3,4,5].findIndex(function(value,index,arr){
return value > 3
}); // 3 (成员 4 的位置)
第二个参数:对象
find() 和 findIndex() 这两个方法都可以接受第二个参数,用来绑定回调函数的 this 对象。
let obj = {num:2}
[1,2,3,4,5].find(function(v){
return v > this.num
},obj)// 3
上面代码中find 方法绑定了 obj 这个对象,所以这里 this.num = 2,所以最终的返回值是 3
数组实例的 fill()
fill () 方法使用给定值,填充一个数组。
['a','b','c'].fill(1)
// [1,1,1]
new Array.(2).fill(1)
// [1,1]
上面代码表明 fill() 方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。
fill() 方法还可以接受第二个参数和第三个参数,用于指定填充的 起始位置和结束位置。
['a','b','c'].fill(7,1,2)
// ['a',7,'c']
注意:如果填充的类型为对象,那么被赋值的是同一个内存地址的对象,而不是深度拷贝对象!
let arr = new Array(2).fill({age:18});
arr[0].age = 17;
// [{age:17},{age:17}]
数组实例的 entries() ,keys(),values()
Es6 提供了三个新方法用来遍历数组:
entries() ,keys(),values()
它们都返回一个遍历器对象,可以用 for..of 循环进行遍历,唯一区别是:
keys() 是对键名的遍历,values() 是对键值的遍历,entries() 是键值对的遍历
for (let index of ['a','b'].keys()) {
console.log(index);
}
// 0
// 1
for (let value of ['a','b'].values()) {
console.log(values);
}
// a
// b
for(let [index,vlaue] of ['a','b'].entries()) {
console.log(index,value);
}
// 0,'a'
// 1,'b'
数组实例的 includes()
Array.protoptype.includes 方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的 includes 方法类似。
[1,2,3].includes(2) // true
[1,2,3].includes(4) // false
该方法的第二个参数表示搜索的起始位置,默认为 0,如果第二个参数为负数,则表示倒数的位置,如果这时他大于数组长度,例如(-4),但是数组长度为3,则会重置为从 0 开始。
[1,2,3].includes(3,3)// false
[1,2,3].includes(3,-4) /// true
另外,Map 和 Set 数据结构有一个 has 方法,需要与 includes 区分
--Map 结构的 has 方法,是用来查找键名的
--Set 结构的 has 方法,是用来查找值的
数组实例的 flat() ,flatMap()
数组成员有时候还是数组,也就是我们说的多维数组,flat() 用于将嵌套的数组拉平。变成一维的数组。该方法返回的是一个新数组,对原来的数组无影响。
[1,2,[3,4]].flat()
// [1,2,3,4]
这里 flat() 方法默认只会拉平一层,如果想要拉平多层,可以将 flat() 方法的参数写成一个整数,表示想要拉平的层数。
[1,2,[3,[4,5]]].flat()
// [1,2,3,[4,5]]
[1,2,[3,[4,5]]].flat(2)
// [1,2,3,4,5]
如果不管有多少层嵌套,都想要拉平,那么就需要使用 Infinity 关键字作为参数
[1,2,[3,[4,5]]].flat(Infinity)
// [1,2,3,4,5]
如果原数组有空位,则 flat() 会跳过空位
[1,2,,4].flat()
// [1,2,4]
flatMap() 方法对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()) 然后对返回值组成的数组执行 flat() 方法。该方法返回一个新数组,不改变原数组。
// 等价于 [[1,2],[2,4],[3,6]].flat()
[1,2,3].flatMap((x) => [x,x*2]);
// [1,2,2,4,3,6]
flatMap() 只能展开一层数组。
flatMap() 方法参数是一个遍历函数,该遍历函数可以接受三个参数,分别是当前数组成员,当前数组成员的位置(从零开始),原数组。
arr.flatMap(function callback(value,index,arr){},thisArg)
flatMap() 方法还可以有第二个参数,用来绑定遍历函数里面的 this
数组的空位
数组的空位是说数组的某一个位置没有任何值,比如 Array 构造函数返回的数组都是空位。
Array(3); // [,,]
注意,空位不是 undefined ,一个位置的值等于 undefined ,依然是有值的,空位是没有任何值。