...
,展开运算符(如果算是运算符);根据基本用途:
语法如下:
/* 用作函数传参:可迭代对象可以是数组、字符串、集合、生成器等等有迭代入口的对象 */
func(0个或更多其他参数, ...可迭代对象, 0个或更多其他参数)
/* 用作构造数组; */
[ 1, 2, ...[3, 4], 5, ...'67890' ]
[...[1, 2], ...[3, 4, 5]] // 像这样的数组拼接,也可以使用 concat 方法
/* 用作构造对象(浅拷贝):也叫属性拷贝什么的 */
let objClone = { ...obj };
尝试使用函数 Math.max / Math.min
求一个数组的最大/最小值:
NaN
;apply
方法,可以将数组或类数组的元素作为参数列表进行传参;const arr = [1, 2, 4];
Math.max(arr) // NaN
Math.max.apply(null, arr) // 4
Math.max(...arr) // 4
Math.max(1, 2, 4) // 4 等价于前两种
Math.max(...'124') // 4 字符串也是可迭代对象
apply
方法使用展开语法,将类数组展开成参数列表:
let args = [1, 2, 3, 4];
sum.apply(null, args) // 10
sum(...args) // 10
sum(...'1234') // 10
sum(1, ...[2, 3], ...[], 4, 5) // 15
function sum(...rest) {
let total = 0;
for (const elem of rest) total += +elem;
return total;
}
/* 1. 复制数组 */
let arr1 = [1, 2, 3];
let arr2 = [...arr1];
let arr3 = arr1.slice()
/* 2. 拼接数组 */
let a1 = [1, 2], a2 = [3, 4];
let a3 = [...a1, ...a2];
let a4 = a1.concat(a2);
/* 1. 复制对象 */
let obj1 = { a: 1, b: 2 }, obj2 = { a: 1, c: 3 };
let o = { ...obj1 };
let oo = Object.assign(obj1);
/* 2. 拼接对象 */
let a1 = [1, 2], a2 = [3, 4];
let a3 = [...a1, ...a2];
let a4 = a1.concat(a2);
[...'hi'] // ['h', 'i']
[...'\u4e2d\u56fd!'] // ['中', '国', '!']
/* 4个字节的 Unicode 字符,如一个火箭表情 */
'\ud83d' //
'\ud83d\ude80' //
'\ud83d\ude80'.length // 2
[...'\ud83d\ude80'].length //1
function* gen() {
yield* [1, 2, 3]
}
let x = [...gen()];
x // [1, 2, 3]
function* fibonacci() {
let current = 0;
let next = 1;
while (true) {
const reset = yield current;
[current, next] = [next, next + current];
if (reset) {
current = 0;
next = 1;
}
}
}
let xx = [...fibonacci()] // 崩掉
...
,含义却像正逆运算;function sum(first=0, ...rest) {
let total = first;
for (const elem of rest) total += +elem;
return total;
}
sum(1, 2, 3, 4) // 10
// 第一个参数 1对应first,其他被收纳到 rest(rest=[2,3,4])
sum(...[1, 2, 3, 4]) // 10
// ...[1, 2, 3, 4] 先展开,等价于 sum(1, 2, 3, 4)
sum(...[], ...[1, 2], 3, 4)