03-解构赋值
# 数组的解构赋值
# 什么是解构赋值
结构赋值:解析某一数据的结构,将我们想要的东西提取出来,赋值给变量或常量。
const arr = [1, 2, 3];
const a = arr[0];
const b = arr[1];
const c = arr[2];
console.log(a, b, c);
// 解构赋值
const [a, b, c] = [1, 2, 3];
console.log(a, b, c);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 数组解构赋值的原理
- 模式(结构)匹配,即两边都是数组结构
- 索引值相同的完成赋值
// 1.模式(结构)匹配
[] = [1, 2, 3];
// 2.索引值相同的完成赋值
const [a, b, c] = [1, 2, 3];
console.log(a, b, c);
// 不取的,可以直接用逗号跳过
const [a, [, , b], c] = [1, [2, 4, 5], 3];
console.log(a, b, c);
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 解构赋值的默认值
// 1.默认值的基本用法
const [a, b] = [];
console.log(a, b); // undefined undefined
const [a = 1, b = 2] = [];
console.log(a, b); // 1 2
1
2
3
4
5
6
2
3
4
5
6
只有当一个数组成员严格等于(===)undefined 时,对应的默认值才会生效。
// 默认值不生效
const [a = 1, b = 2] = [3, 0];
const [a = 1, b = 2] = [3, null];
// b 默认值生效
const [a = 1, b = 2] = [3];
1
2
3
4
5
6
2
3
4
5
6
如果默认值是表达式,默认值表达式是惰性求值的。
const func = () => {
console.log('我被执行了');
return 2;
};
// 这种情况用不到默认值,func 函数不会执行
const [x = func()] = [1];
// 这种情况会取默认值,func 函数执行
const [x = func()] = [];
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 数组解构赋值的应用
# 常见类数组的解构赋值
对于常见的类数组的结构赋值,这里要注意类数组不是真正的数组,不能调用数组的方法。
(1)arguments
// arguments 只存在于非箭头函数,表示参数列表
function func() {
const [a, b] = arguments;
console.log(a, b);
}
func(1, 2);
1
2
3
4
5
6
7
2
3
4
5
6
7
(2)NodeList
// NodeList 存放了按条件筛选出的元素
const [p1, p2, p3] = document.querySelectorAll('p');
console.log(p1, p2, p3);
1
2
3
2
3
# 函数参数的解构赋值
数组结构赋值还常用于函数形参上。以求数组中两个元素的和为例:
// 不使用解构
const add1 = arr => arr[0] + arr[1];
// 使用解构
const add2 = ([x = 0, y = 0]) => x + y;
const array = [3, 4];
add1(array);
add2(array)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 交换变量的值
原来交换两个变量的值,需要借助临时变量。
let x = 1;
let y = 2;
// 借助临时变量交换两个变量的值
let tmp = x;
x = y;
y = tmp;
console.log(x, y);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
现在使用解构赋值可以不借助临时变量,一行代码搞定。
[x, y] = [y, x];
1
# 对象的解构赋值
# 对象解构赋值的原理
- 模式(结构)匹配,两边都是对象结构
- 属性名相同的完成赋值
// 属性名匹配即可,不需要按顺序
const { age, username } = {
username: 'Alex',
age: 18
};
console.log(age, username);
1
2
3
4
5
6
7
2
3
4
5
6
7
其实对象的结构赋值的完整写法是这样的:
const { age: age, username: username } = {
username: 'Alex',
age: 18
};
console.log(age, username);
1
2
3
4
5
6
2
3
4
5
6
根据这个,就可以理解对象结构赋值中取别名的用法了:
const { age: age, username: uname } = {
username: 'Alex',
age: 18
};
console.log(age, uname);
1
2
3
4
5
6
2
3
4
5
6
# 对象解构赋值的注意事项
- 对象解构赋值的默认值
- 将一个已经声明的变量用于解构赋值
- 可以取到继承的属性
(1)默认值
对象的属性值严格等于 undefined 时,对应的默认值才会生效
const { username = 'ZhangSan', age = 0 } = {
username: 'alex'
};
console.log(username, age); // alex 0
1
2
3
4
5
2
3
4
5
(2)默认值表达式
如果默认值是表达式,默认值表达式是惰性求值的
(3)将一个已经声明的变量用于解构赋值
如果将一个已经声明的变量用于对象的解构赋值,整个赋值需在圆括号中进行。
let x = 2;
// 错误写法,浏览器会误认为前面的花括号是镖师一个代码块
// { x } = { x: 1 }
// 正确写法
({ x } = { x: 1 })
console.log(x);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
(4)以取到继承的属性
// 获取继承的 toString 方法, 解构赋值
const { toString } = {};
console.log(toString);
1
2
3
4
2
3
4
# 对象解构赋值的应用
(1)函数参数的解构赋值
// 不使用解构,形参为一个对象 user
const userInfo1 = user =>
console.log(user.username, user.age);
// 用解构来接收对象参数
const userInfo2 = ({ age = 0, username = 'ZhangSan' }) =>
console.log(username, age);
userInfo1({ username: 'alex', age: 18 });
userInfo2({ username: 'alex'});
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
(2)复杂的嵌套
const obj = {
x: 1,
y: [2, 3, 4],
z: {
a: 5,
b: 6
}
};
// const { x, y, z } = obj;
// console.log(x, y, z);
const {
y,
y: [, yy],
z,
z: { b }
} = obj;
console.log(yy, y, z, b);
/*
yy == 3
y == [2, 3, 4]
z == { a: 5, b: 6 }
b == 6
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 其他数据类型的解构赋值
(1)字符串的解构赋值
字符串既可以用数组的形式解构赋值,也可以用对象的形式解构赋值。
数组形式可以获取对象下标的字符。
// 数组形式的解构赋值
const [a, b, , , c] = 'hello';
console.log(a, b, c); // h e o
1
2
3
2
3
对象形式除了可以获取对应下标的字符,还可以获取数组的其他属性,比如 length。
// 对象形式的解构赋值
const { 0: a, 1: b, length } = 'hello';
console.log(a, b, length); // h e 5
1
2
3
4
2
3
4
(2)数值和布尔值的解构赋值
数值和布尔值在解构赋值时,会先将其转换为对应的包装对象,再按照对象的形式进行解构赋值。
// 数值解构赋值相当会右边是 new Number(123)
const { a, toString } = 123;
console.log(a, toString); // a 为 undefined,toString 取到继承的属性
// 布尔值也类似
const { b = 2, toString } = true;
console.log(b, toString); // b 取默认值 2,toString 为继承的属性
1
2
3
4
5
6
7
2
3
4
5
6
7
(3)undefined 和 null 的解构赋值
由于 undefined 和 null 都没有对应的包装对象,无法转为对象,所以对它们进行解构赋值,都会报错。
编辑 (opens new window)
上次更新: 2023/06/04, 12:34:19