目录
至于什么是解构赋值,我们先来看下面的这个示例,然后再来具体地讲述解构赋值:
<script>
//原始方式
// 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);
</script>
那么究竟什么是解构赋值呢?
解析某一数据的结构,将我们想要的东西提取出来,赋值给变量或常量
下面就来具体看看解构赋值的应用吧!
一、数组的解构赋值
1、数组解构赋值的原理:
a.模式(结构)匹配
例如: [] = [1, 2, 3];(数组对数组、对象对对象)
b.索引值相同的完成赋值
例如:const [a, b, c] = [1, 2, 3];
示例:
<script>
// 不取的,可以直接用逗号跳过
const [a, [, , b], c] = [1, [2, 4, 5], 3];
console.log(a, b, c);
</script>
2.数组解构赋值的默认值
a.默认值的基本用法
这是未设置默认值之前:
const [a, b] = [];
console.log(a, b); //[undefined undefined]
这是设置默认值之后:
<script>
const [a = 1, b = 3] = [];
console.log(a, b); //[1 3]
</script>
b.默认值的生效条件
只有当一个数组成员严格等于(===)undefined 时,对应的默认值才会生效
<script>
// const [a = 1, b = 2] = [3, 0];//-->[3 0]
// const [a = 1, b = 2] = [3, null];//-->[3 null]
//const [a = 1, b = 2] = [3];其实就等价于 const [a = 1, b = 2] = [3,undefined];
const [a = 1, b = 2] = [3]; //-->[3 2]
console.log(a, b);
</script>
c.默认值表达式
如果默认值是表达式,则默认值表达式是惰性求值的
<script>
const func = () => {
console.log('我被执行了');
return 2;
};
// const [x = func()] = [1]; //-->1
const [x = func()] = [];
console.log(x);
</script>
注意点:
在数组解构赋值中,等号左边的格式和等号右边的格式一模一样时,才能解构
在数组解构赋值中,左边的个数可以和右边的个数不一样,右边的个数可以和左边的个数不一样(当左边个数大于右边时,多余的用undefined表示,也可以给左边指定默认值)
在数组解构赋值中,还可以使用ES6中新增的扩展运算符来打包剩余的数据:
在数组解构赋值中,如果使用了扩展运算符,那么扩展运算符只能写在最后:
let [a,...b]=[1,3,5];
console.log("a="+a);
console.log(b);
3.数组解构赋值的应用
a.常见的类数组的解构赋值
示例1
<script>
// arguments
function func() {
// console.log(arguments);
// console.log(arguments.push);
const [a, b] = arguments;
console.log(a, b);
}
func(1, 2);
</script>
示例2
<p>123</p>
<p>321</p>
<p>34567</p>
<script>
// NodeList
console.log(document.querySelectorAll('p'));
const [p1, p2, p3] = document.querySelectorAll('p');
console.log(p1, p2, p3);
</script>
b.函数参数的解构赋值
之前的做法:
<script>
const array = [1, 1];
const add = arr => arr[0] + arr[1];
console.log(add(array));
</script>
现在的做法:
<script>
const array = [1, 1];
const add = ([x = 0, y = 0]) => x + y;
console.log(add(array));
</script>
<script>
const array = [1, 1];
const add = ([x = 0, y = 0]) => x + y;
console.log(add([]));
</script>
c.交换变量的值
<script>
let x = 1;
let y = 2;
//原来的方法
// let tmp = x;
// x = y;
// y = tmp;
// console.log(x, y);
//现在的方法
[x, y] = [y, x];
[x, y] = [2, 1];
console.log(x, y);
</script>
总结:
- 赋值运算符 = 左侧的 [] 用于批量声明变量,右侧数组的单元值将被赋值给左侧的变量
- 变量的顺序对应数组单元值的位置依次进行赋值操作
- 变量的数量大于单元值数量时,多余的变量将被赋值为 undefined
- 变量的数量小于单元值数量时,可以通过 ... 获取剩余单元值,但只能置于最末位
- 允许初始化变量的默认值,且只有单元值为 undefined 时默认值才会生效
- 注:支持多维解构赋值,比较复杂后续有应用需求时再进一步分析
二、对象的解构赋值
1.对象解构赋值的原理
把属性名当做变量名即可
a.模式(结构)匹配
{}={}
在对象解构赋值中, 左边的变量名称必须和对象的属性名称一致, 才能解构出数据
b.属性名相同的完成赋值
<script>
//username: 'Alex', age: 18
//不一定要age--age;username--username一一对应,只要属性名对上即可
//简写形式
// const {
// age,
// username
// } = {
// username: 'Alex',
// age: 18
// };
//完整的形式 这里的单引号可以省略
const {
'age': age,
'username': username
} = {
username: 'Alex',
age: 18
};
console.log(age, username);
</script>
c.取别名
<script>
const {
age: age,
username: uname
} = {
username: 'Alex',
age: 18
};
console.log(age, uname);
</script>
2.对象解构赋值的注意事项
a.对象解构赋值的默认值
对于这一部分跟数组解构默认值一样,这里就不过多的阐述了
默认值的生效条件
对象的属性值严格等于 undefined 时,对应的默认值才会生效
<script>
const {
username = 'ZhangSan', age = 0
} = {
username: 'alex'
};
console.log(username, age);
</script>
默认值表达式
如果默认值是表达式,默认值表达式是惰性求值的,这里具体可以看上面的数组的相关部分
b.将一个已经声明的变量用于解构赋值
如果将一个已经声明的变量用于对象的解构赋值,整个赋值需在圆括号中进行
<script>
//未声明
// let {
// x
// } = {
// x: 1
// };
// console.log(x); //1
//声明
let x = 2;
//写法1
({
x
} = {
x: 1
});
//写法2
// [x] = [1];
console.log(x); //1
</script>
c.可以取到继承的属性
<script>
// const {
// a = 1
// } = {};
// console.log(a); //1
const {
toString
} = {};
// console.log(toString);
// Object.prototype
// console.log(Object.prototype);
console.log({});
</script>
3.对象解构赋值的应用
a.函数参数的解构赋值
示例1:
<script>
//原来的做法
// const logPersonInfo = user => console.log(user.username, user.age);
const logPersonInfo = ({
age = 0,
username = 'ZhangSan'
}) =>
console.log(username, age);
logPersonInfo({
username: 'alex',
age: 18
});
</script>
b.复杂的嵌套
示例1:
<script>
const obj = {
x: 1,
y: [2, 3, 4],
z: {
a: 5,
b: 6
}
};
const {
x,
y,
z
} = obj;
console.log(x, y, z);
</script>
示例2:
<script>
const obj = {
x: 1,
y: [2, 3, 4],
z: {
a: 5,
b: 6
}
};
const {
y,
y: [, yy],
z,
z: {
b
}
} = obj;
console.log(yy, y, z, b);
</script>
总结:
- 赋值运算符 = 左侧的 {} 用于批量声明变量,右侧对象的属性值将被赋值给左侧的变量
- 对象属性的值将被赋值给与属性名相同的变量
- 对象中找不到与变量名一致的属性时变量值为 undefined
- 允许初始化变量的默认值,属性不存在或单元值为 undefined 时默认值才会生效
- 注:支持多维解构赋值,比较复杂后续有应用需求时再进一步分析
三、其他数据类型解构赋值
1.字符串的解构赋值
字符串既可以按数组形式来解构赋值,也可以按对象形式来解构赋值
a.数组形式的解构赋值
<script>
const [a, b, , , c] = 'hello';
console.log(a, b, c);
</script>
b.对象形式的解构赋值
<script>
const {
0: a,
1: b,
length //直接去到字符串的length属性
} = 'hello';
console.log(a, b, length);
console.log('hello'.length);
</script>
2.数值和布尔值的解构赋值
a.数值解构赋值
<script>
// 先将等号右边的值转为对象
console.log(new Number(123));
const {
a = 1, toString
} = 123;
console.log(a);
console.log(toString);
</script>
b.布尔值解构赋值
<script>
const {
b = 2, toString
} = true;
console.log(b);
console.log(toString);
</script>
3.undefined 和 null 的解构赋值
由于 undefined 和 null 无法转为对象,所以对它们进行解构赋值,都会报错
a.undefined解构赋值
<script>
const {
toString
} = undefined;
</script>
b.null解构赋值
<script>
const {
toString
} = null;
</script>