4、数组扩展之扩展运算符

扩展运算符(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()方法变通解决。

用途

//复制数组

//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" ]

5、数组扩展之Array.from()方法

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]

6、数组扩展之Array.of()方法

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

06-27 20:42