解构赋值
开发过程中遇到结构复杂的取值时,结构赋值方便了很多
结构赋值是什么:
(1)认识解构赋值:
传统的通过数组的下标来获取数组中的元素:
const arr = [1, 2, 3];
const a = arr[0];
const b = arr[1];
const c = arr[2];
console.log(a, b, c); // 1 2 3
通过解构赋值来获取元素的小栗子:
const [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 1 2 3
(2)什么是解构赋值:
解析某一数据的结构,将我们想要的东西提取出来,赋值给变量或常量。
数组的解构赋值:
(1)数组解构赋值的原理:
1、模式(结构)匹配。
等号两边的结构相同,简单理解为:左边是数组右边也是数组,左边是对象右边也是对象。
// 1.模式(结构)匹配
[] = [1, 2, 3];
2、索引值相同的完成赋值。
const [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 1 2 3
在这里栗子中 a 与 1 对应,b 与 2 对应,c 与 3 对应。
注意:数组解构赋值中不取的,可以直接用逗号跳过。看下面例子:
const [a, [, , b], c] = [1, [2, 4, 5], 3];
console.log(a, b, c); // 1 5 3
(2)数组解构赋值的默认值:
1、默认值的基本用法:
先举个小栗:
const [a, b] = [];
console.log(a,b);
问打印出什么?想必大家都猜到了是 undefined undefined 原因是const [a,b] = []相当于const [a,b] = [undefined,undefined],所以是undefined,其实没有太大意义。
在这里先举个默认值的例子:
const [a = 1, b = 2] = [];
console.log(a, b); // 1 2
2、默认值的生效条件:
只有当一个数组成员严格等于(===)undefined 时,对应的默认值才会生效!
举例:
const [a = 1, b = 2] = [3, 0];
console.log(a,b); // 3 0
这里很简单,因为右边不等于undefined,所以打印出来的就不是默认值。
再举个例子:
const [a = 1, b = 2] = [3, null];
console.log(a,b);
在这里大家思考一下a b分别是多少?答案是 3 null ,3就很好理解,null是因为必须严格等于undefined,但null严格意义下不是undefined,所以是null。
再来个小栗子:
const [a = 1, b = 2] = [3];
console.log(a,b); // 3 2
// 3后面没有值了,所以默认就是undefined,所以默认值起效,就是2
3、默认值是表达式:
如果默认值是表达式,默认值表达式是惰性求值的。
const func = () => {
console.log('我被执行了');
return 2;
};
const [x = func()] = [1];
console.log(x); // 1
这个例子中函数并没有被执行,打印出来的是 1 ,原因是浏览器不会浪费性能去执行一遍用不到的表达式,因为右边数组中有1。
那,什么时候会执行呢?
const func = () => {
console.log('我被执行了');
return 2;
};
const [x = func()] = [];
console.log(x); // 我被执行了 2
这样就会执行了!
总结一句:用得到的就会执行,用不到的不会执行!
如果上面大家都能理解,那说明你已经掌握了解构赋值的基本原理,但别急,下面还有东西。
(3)数组解构赋值在实际开发总的应用:
1、常见的类数组的解构赋值:
虽然arguments不是数组,但可以对arguments进行数组般的解构赋值。
function func() {
const [a, b] = arguments;
console.log(a, b);
}
func(1, 2);
大家可能会想两边结构不一样怎么能会解构赋值呢?在这里给大家说一下,大家可以把这种情况看作是特例记住就行了,不需要深究。(后面博客中会对这种情况进行讲解)
Nodelist的结构赋值:
<p>123</p>
<p>321</p>
<p>34567</p>
<script>
console.log(document.querySelectorAll('p'));
const [p1, p2, p3] = document.querySelectorAll('p');
console.log(p1, p2, p3);
</script>
在这里Nodelist虽然也不是真正意义上的数组,但仍然可以通过解构赋值的方法去获取里面的元素。
2、函数参数的解构赋值:
const array = [1, 1];
// const add = arr => arr[0] + arr[1]; // 普通数组里面值相加
const add = ([x = 0, y = 0]) => x + y; // 通过解构赋值求和
console.log(add(array)); // 2
console.log(add([])); // 0
// 传有值的数组时就向函数里面传相应的值进去,传空数组时向函数里面传的就是默认值
3、交换变量的例子:
let x = 1;
let y = 2;
// 以前的写法:
// let tmp = x;
// x = y;
// y = tmp;
// console.log(x, y);
// 学完解构赋值的写法:
[x, y] = [y, x];
console.log(x, y);
对象的解构赋值:
(1)对象解构赋值的原理:
1、模式(结构)匹配:
{}={}
2、属性名相同的完成赋值:不一定必须按顺序
举个例子:对象简写形式:
const { age, username } = { username: 'Alex', age: 18 }; // 简写
console.log(age, username); // 18 Alex
这个例子中是属性名与属性值的名字一样,所以可以省略。
完整写法:
const { age: age, username: username } = { username: 'Alex', age: 18 };
console.log(age, username);
这里age是属性名age相对的值age,username是属性名username对应的值username,若不好理解请看下面的改写版:
const { age: age1, username: username1 } = { username: 'Alex', age: 18 };
console.log(age1, username1); // 18 Alex
console.log(age,username); // 报错
切记,这里age1对应的是属性名age的值age1,username1对应的是属性名username的值username1,一一对应,千万不要当成属性名了!明白这个之后下面的取别名也就相应好理解了。
3、取别名:
const { age: age, username: uname } = { username: 'Alex', age: 18 };
console.log(age, uname); // 18 Alex
原理同上!
(2)对象结构赋值的注意事项:
1、默认值的生效条件:
对象的属性值严格等于 undefined 时,对应的默认值才会生效。
const { username = 'ZhangSan', age = 0 } = { username: 'alex' };
// 上式等号右边相当于 { username: 'alex' , age: undefined}
console.log(username, age); // alex 0
注意:给对象的属性设置默斜体样式认值时用等号!
默认值都是等号,不管是数组还是对象!
2、默认值表达式:
如果默认值是表达式,默认值表达式是惰性求值的!
3、将一个已经声明的变量用于解构赋值:
如果将一个已经声明的变量用于对象的解构赋值,整个赋值需在圆括号中进行
举个错误例子:
let x = 2;
let {x} = {x:1}; // Identifier 'x' has already been declared
这种写法会报重复声明的错误!
报重复声明的错误,大家可能会想,我不重复声明不就完事了,但还是不行。见代码:
let x = 2;
{x} = {x:1}; // 这样写会造成浏览器对花括号的误解,浏览器会把x外边的花括号当成代码块的花括号而不是对象的花括号 // Unexpected token '='
// 但浏览器不会将数组的[]理解成代码块
// [x] = [1]; // 不会报错
这样写会报语法错误! Unexpected token ‘=’
正确写法:
let x = 2;
({ x } = { x: 1 });
console.log(x); // 1
4、可以取到继承的属性:
了解即可
const { toString } = {};
console.log(toString); // ƒ toString() { [native code] }
// 这里的toString就是继承Object下的toString
(3)对象解构赋值的应用:
1、传参:
以前传参传的是对象的情况:
const logPersonInfo = user => console.log(user.username, user.age);
logPersonInfo({ username: 'alex', age: 18 }); // alex 18
学习完解构赋值:
// 这种写法时:要注意形参外边的一对括号
const logPersonInfo = ({ age, username }) =>console.log(username, age);
logPersonInfo({ username: 'alex', age: 18 }); // alex 18
其他数据类型的解构赋值:
1、字符串的解构赋值:
这种左边是字符串右边也是字符串的想当然的解构赋值是错误的写法:
看这颜色就不靠谱(小声bb)
' '='hello'
字符串比较特殊,既可以数组形式的解构赋值,也可以对象形式的解构赋值:
// 数组形式的解构赋值
const [a, b, , , c] = 'hello';
console.log(a, b, c); // h e o
// 对象形式的解构赋值
const { 0: a, 1: b, length } = 'hello';
console.log(a, b, length); // h e 5
console.log('hello'.length); // 5
// 字符串的length属性
注意:当以对象形式对字符串进行解构赋值时,其对象的属性名就是字符串的索引值!
const {5:a,1:c,v:v}='hello';
console.log(a,c,v); // undefined "e" undefined
2、数值和布尔值的解构赋值:
先将等号右边的值转为对象。
对数值:
const { a = 1, toString } = 123;
console.log(a, toString); // 1 ƒ toString() { [native code] }
将数值转化为对象时,变成一个空对象,故 a 是1 ,因为是对象,即它能继承Object的属性值toString
对布尔值:
const { b = 2, toString } = true;
console.log(b, toString); // 2 ƒ toString() { [native code] }
这里讲的数值和布尔值的解构赋值一般用不着,因此不需要深究,当作扩展知识就行。
3、对undefined和null的解构赋值:
由于 undefined 和 null 无法转为对象,所以对它们进行解构赋值,都会报错!
const { toString } = undefined;
const { toString } = null;
本文来自博客园,作者:喆星高照,转载请注明原文链接:https://www.cnblogs.com/houxianzhou/p/17664026.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?