1. 拓展运算符…
(1)基本用法
- 数组转参数序列(逗号分隔)
let arr = [1,2,3];
console.log(...arr); // 1 2 3
- 函数调用
let arr = [1,2];
function add(x,y) {
console.log(x+y);
};
add(...arr); // 3
- 扩展运算符可以放置表达式
const arr = [
...(x>0 ? ['a']:[]),
'b',
]
- 如果扩展运算符后面是一个空数组,则不产生任何效果
(2)代替数组的apply方法
function fn(x, y, z) {
console.log(x, y, z);
};
let args = [1,2,3];
// ES5写法
fn.apply(null, args); // 1 2 3
// ES6写法
fn(...args); // 1 2 3
- 简化求出一个数组最大元素
let args = [1,2,3,4,5];
// ES5 写法
console.log(Math.max.apply(null,args)) // 5
// ES6 写法
console.log(Math.max(...args)); // 5
- 通过push函数,将一个数组添加到另一个数组的尾部
let arr1 = [1,2,3];
let arr2 = [4,5,6];
// ES5 写法
Array.prototype.push.apply(arr1,arr2)
console.log(arr1); // [ 1, 2, 3, 4, 5, 6 ]
// ES6 写法
arr1.push(...arr2);
console.log(arr1); // [ 1, 2, 3, 4, 5, 6 ]
console.log([...arr1, ...arr2]); // [ 1, 2, 3, 4, 5, 6 ]
(3)扩展运算符的应用
- 合并数组
let arr1 = [1,2,3];
let arr2 = [4,5,6];
console.log([...arr1, ...arr2]); // [ 1, 2, 3, 4, 5, 6 ]
- 与解构赋值结合
let arr = 'abc,def';
let [x,y] = arr.split(',');
console.log([x,...y]); // [ 'abc', 'd', 'e', 'f' ]
- 函数的返回值
let dateFields = readDateFields(database);
let d = new Date(...dateFields);
- 字符串
console.log([...'Katrina']) // ['K', 'a', 't','r', 'i', 'n','a']
- 实现Iterator接口的对象
- Map与Set结构,Generator函数
let m = new Map([
[1,'one'],
[2,'two'],
[3,'three'],
]);
console.log([...m]); // [ [ 1, 'one' ], [ 2, 'two' ], [ 3, 'three' ] ]
2. Array相关
(1)Array.from()
let arrayLike = {
'0':'a',
'1':'b',
'2':'c',
length:3,
};
// ES5 写法
let arr1 = [].slice.call(arrayLike);
console.log(arr1); // [ 'a', 'b', 'c' ]
// ES6 写法
let arr2 = Array.from(arrayLike);
console.log(arr2); // [ 'a', 'b', 'c' ]
- Array.from接受第二个参数,可指定回调函数,作用类似于数组种的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组
let arr = [1,2,3];
let arr1 = Array.from(arr, item => item*2);
console.log(arr1); // [ 2, 4, 6 ]
- 可用于生成指定start和end的连续数组
let start = 2, end = 6;
console.log(Array.from(new Array(end+1).keys()).slice(start)); // [ 2, 3, 4, 5, 6 ]
- 数组去重
let arr = [1,2,1,3];
let newArray = Array.from(new Set(arr));
console.log(newArray); // [ 1, 2, 3 ]
(2)Array.of()
Array.of(1,2,3) // [1,2,3]
Array() // [];
Array(3) // [ , , ];
Array(3, 2, 1) // [3,2,1];
不难看出,Array
方法没有参数、一个参数、三个参数时,返回的结果都不一样,只有当参数个数不小于2的时候,Array()才会返回由参数组成的新数组
所以,Array.of()基本上可以用于代替Array()或者new Array(),并且不存在由于参数不同而导致的重载
Array.of()的行为可以通过以下代码实现:
function ArrayOf() {
return [].slice.call(arguments);
}
(3)copyWithin()
语法为:
Array.prototype.copyWithin(target, start=0, end=this.length);
- target(必须):从该位置开始替换数据
- start(可选):从该位置开始读取数据,默认为0, 如果为负数,则表示倒数
- end(可选):到该位置前停止读取数据,默认等于数组长度,如果为负值,则表示倒数
let arr = [1,2,3,4,5,6,7,8];
console.log(arr.copyWithin(1,3,5)); // [1, 4, 5, 4,5, 6, 7, 8 ]
(4)Array.find() && Array.findIndex()
let arr = [1,2,3,4,5,6,7,8];
console.log(arr.find(item => item > 5)); // 6
console.log(arr.findIndex(item => item > 5)); // 5
(5)Array.fill()
let arr = [1,2,3,4,5,6,7,8];
console.log(arr.fill(10)); // [10, 10, 10, 10, 10, 10, 10, 10]
(6)Array.entries() Array.keys() Array.values()
(7)Array.includes()
let arr = [1,2,3,4,5,6,7,8];
console.log(arr.includes(3, 5)); // false 因为3在搜索位置后面没有出现
includes
解决了indexOf
的缺点:
(1)不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1
(2)它内部使用严格相等运算符(===
)进行判断,这会导致对NaN
进行误判
[NaN].indexOf(NaN); // -1
[NaN].includes(NaN); // true
includes
需要和set
与map
中的has
进行区分
(1)map
中的has
用于查找键名
(2)set
中的has
用于查找值
(8)数组的空位
Array(3) // [ , , ]
在ES5中,大多数情况下会忽略空位:
forEach()
,filter()
,every()
,some()
都会跳过空位map()
会跳过空位,但会保留这个值join()
和toString()
会将空位视为undefined
,而undefined
和null
会被处理成为字符串
在ES6中,不会忽略空位,而是明确将空位转为undefined
- Array.from()
- 扩展运算符…
- copyWithin()会连着空位一起拷贝
- fill()会将空位视为正常的数组位置
- for of循环也会遍历空位, 但是如果改为map遍历,空位会跳过
下列方法都会处理成undefined - Array.entries()
- Array.keys()
- Array.values()
- Array.find()
- Array.findIndex()