01-剩余参数与展开运算符
# 剩余参数
# 函数参数中的剩余参数
剩余参数类似于 Java 中的可变参数。JavaScript 中的剩余参数永远是个数组,即使没有值,也是空数组
const add = (x, y, ...args) => {
console.log(x, y, args);
};
add(); // undefined undefined []
add(1); // 1 undefined []
add(1, 2); // 1 2 []
add(1, 2, 3, 4, 5); // 1 2 [3, 4, 5]
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
箭头函数的参数部分即使只有一个剩余参数,也不能省略圆括号。
const add = (...args) => {};
1
箭头函数可以使用剩余参数替代普通函数中的 arguments 获取实际参数。
const add1 = function () {
console.log(arguments);
};
const add2 = (...args) => {
console.log(args);
};
1
2
3
4
5
6
7
2
3
4
5
6
7
剩余参数只能是最后一个参数,之后不能再有其他参数,否则会报错。
# 解构赋值中的剩余参数
剩余参数不一定非要作为函数参数使用,还可以用于解构赋值。
数组剩余参数的解构赋值:
const [num, ...args] = [1, 2, 3, 4];
console.log(num, args); // 1 [2, 3, 4]
const func = ([num, ...args]) => {};
func([1, 2, 3]);
1
2
3
4
5
2
3
4
5
对象剩余参数的解构:
const { x, y, ...z } = { a: 3, x: 1, y: 2, b: 4 };
console.log(x, y, z); // 1 2 { a: 3, b: 4 }
const func = ({ x, y, ...z }) => {};
func({ a: 3, x: 1, y: 2, b: 4 });
1
2
3
4
5
2
3
4
5
# 展开运算符
# 数组的展开运算符
# 什么是展开运算符
什么是展开运算符,通过一个例子介绍。我们要获取一个数组中最小的元素,怎么实现呢。可以想到 Math.min()
,但是这个函数的参数不是数组,这时候就可以用到展开运算符。
let res = Math.min(...[3, 1, 2]);
// 相当于:
let res2 = Math.min(3, 1, 2)
1
2
3
4
2
3
4
可以看到展开运算符和剩余参数的语法相同,如何区分呢?
- 展开运算符是将数组展开为元素列表,[3,1,2] -> 3,1,2
- 剩余参数是将元素列表转换为数组,3,1,2 -> [3,1,2]
// 展开运算符
let arr = [...[1, 2, 3], 4]; // [1, 2, 3, 4]
// 剩余参数
let [a, ...b] = [1, 2, 3, 4]
console.log(a) // 1
console.log(b) // [2, 3, 4]
1
2
3
4
5
6
7
2
3
4
5
6
7
# 数组展开运算符的应用
(1)复制数组
const a = [1, 2];
// 使用展开运算符创建出 a 数组的副本
const b = [...a];
1
2
3
4
2
3
4
(2)合并数组
const a = [1, 2];
const b = [3];
const c = [4, 5];
// 合并数组 a、b、c,并且追加了一个元素 1
const all = [...a, ...b, ...c, 1]
1
2
3
4
5
6
2
3
4
5
6
(3)字符串转为数组
// 字符串可以按照数组的形式展开
console.log(...'alex'); // a l e x
// 字符串转数组
const arr = [...'alex']; // ['a', 'l', 'e', 'x']
// 相当于
const arr2 = 'alex'.split('');
1
2
3
4
5
6
7
2
3
4
5
6
7
(4)常见的类数组转化为数组
// arguments
function func() {
// console.log(arguments.push);
console.log([...arguments]);
}
func(1, 2);
// NodeList
console.log(document.querySelectorAll('p'));
console.log([...document.querySelectorAll('p')].push);
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 对象的展开运算符
# 展开对象
展开对象要放在 {}
中,得到一个新对象。
const apple = {
color: '红色',
shape: '球形',
taste: '甜'
};
const apple2 = { ...apple };
1
2
3
4
5
6
7
2
3
4
5
6
7
可以用来合并对象,如果由相同属性,后面的覆盖前面的。
const apple = {
color: '红色',
shape: '球形',
taste: '甜'
};
const pen = {
color: '黑色',
shape: '圆柱形',
use: '写字'
};
const applePen = { ...apple, ...pen };
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 对象展开运算符的注意事项
如果展开一个空对象,则没有任何效果
console.log({ ...{} }); // {}
console.log({ ...{}, a: 1 }); // {a: 1}
1
2
2
如果展开的不是对象,则会自动将其转为对象,再将其属性罗列出来。
// 下面打印出的都是空对象 {}
console.log({ ...1 });
console.log(new Object(1));
console.log({ ...undefined });
console.log({ ...null });
console.log({ ...true });
1
2
3
4
5
6
2
3
4
5
6
如果展开运算符后面是字符串,它会自动转成一个类似数组的对象,因此返回的不是空对象。
console.log({ ...'alex' }); // {0: 'a', 1: 'l', 2: 'e', 3: 'x'}
console.log([...'alex']); // ['a', 'l', 'e', 'x']
console.log(...'alex'); // a l e x
1
2
3
2
3
对象中对象属性不会递归展开。
const apple = {
color: 'red',
feature: {
taste: '甜'
}
};
// 不会展开 feature 中的属性
console.log({ ...apple });
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 对象展开运算符的应用
可以用来复制对象和合并对象,前面已经说过了。
还可以用来属性覆盖,其实就是用合并对象的方式覆盖属性。比如由默认参数和用户自定义参数,没传自定义参数就取默认值,否则用用户自定义参数。
const logUser = userParam => {
// 默认参数
const defaultParam = {
username: 'ZhangSan',
age: 0,
sex: 'male'
};
// 用户参数覆盖默认参数
const finalParam = { ...defaultParam, ...userParam };
console.log(finalParam.username);
};
logUser();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
编辑 (opens new window)
上次更新: 2023/06/04, 12:34:19