扩展运算符(spread)是三个点( … )。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列
var arr=[1,2,3];
[9,8,...arr]; //[9, 8, 1, 2, 3]
['a',...[1,2]]; //(3) ['a', 1, 2]
//空数组不会有有变化和报错
[...[],8]; //[8]
//作为函数的参数
function f(v, w, x, y, z) {
console.log(v,w,x,y,z);
}
const args = [0, 1];
f(-1, ...args, 2, ...[3]);//-1 0 1 2 3
//放置表达式
const x=4;
[ ...(x > 0 ? ['a'] : []),'b'];//(2) ['a', 'b']
以下语法会报错
(...[1, 2]);
...[1,2];
console.log((...[1, 2]));
扩展运算符取代apply()方法
// ES5 的写法
Math.max.apply(null, [14, 3, 77])
//不使用apply
Math.max(14, 3, 77);//77
// ES6 的写法
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77);
JavaScript 中 call()、apply()、bind() 的用法:https://www.runoob.com/w3cnote/js-call-apply-bind.html
push()方法中运用扩展运算符
// ES6 的写法
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1.push(...arr2);
Math对象max()方法和push()方法参数都不能使用数组,所以ES5使用时需要使用apply()方法变通解决。
用途
注意:
数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组
const a1 = [1, 2];
const a2 = a1; //这种复制会两个数组会互相影响
a2[0] = 2;
a1 // [2, 2]
//复制数组
//ES5复制数组
const a1 = [1,2];
const a2=a1.concat();
//ES6复制数组
const a3 = [...a1];
a3[0]='11';
a3;//['11', 2]
a1;//[1, 2]
//ES6合并数组
const a4=[...a1,...a2,...a3]
如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest // [2, 3, 4, 5]
const [first, ...rest] = [];
first // undefined
rest // []
const [first, ...rest] = ["foo"];
first // "foo"
rest // []
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-like object)和可遍历(iterable)的对象
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// ES5 的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
//使用for...in循环
let narr=[];
for(let i in arrayLike){
narr.push(arrayLike[i]);
}
narr;//['a', 'b', 'c', 3]
// ES6 的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
实际应用中,常见的类似数组的对象是 DOM 操作返回的 NodeList 集合,以及函数内部的arguments对象。Array.from()都可以将它们转为真正的数组
// NodeList 对象
//<p>AA</p>
//<p>BB</p>
//<p>CC</p>
let ps = document.querySelectorAll('p');
//过滤出来内容为AA的P标签
Array.from(ps).filter(p => {
return p.textContent == 'AA';
});
// arguments对象
function sum(a,b){
console.log(arguments);
console.log(Array.from(arguments));//[1,5]
return a+b;
}
sum(1,5);
//字符串和 Set 结构都具有 Iterator 接口
Array.from('hello');// ['h', 'e', 'l', 'l', 'o']
let namesSet = new Set(['a', 'b'])
Array.from(namesSet) // ['a', 'b']
//如果参数是一个真正的数组,Array.from()会返回一个一模一样的新数组
Array.from([1, 2, 3]); [1, 2, 3]
第二个参数
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]
Array.of()方法用于将一组值,转换为数组;
这个方法的主要目的,是弥补数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的行为有差异
Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]
Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(undefined) // [undefined]
//结合扩展运算符使用
Array.of(...[4,5,8]);
其他参考:https://es6.ruanyifeng.com/#docs/array#Array-of