Open Genzhen opened 3 years ago
let a = 1, b = 2, head = { next: { next: 1 } }; [a, b] = [b, a]; [head.next, head.next.next] = [head.next.next, head.next]; console.log(a, b, head);
每日一题会在下午四点在交流群集中讨论,五点小程序中更新答案 欢迎大家在下方发表自己的优质见解 二维码加载失败可点击 小程序二维码
2 1 {next:1}
通过解构赋值可以交换两个变量的值,所以 [a,b] = [b,a],但是对象就需要注意下了。
[a,b] = [b,a]
head = { next: { next: 1 } }; [head.next, head.next.next] = [head.next.next, head.next];
注意解构的过程,来分析下 [head.next,head.next.next] = [head.next.next,head.next]
[head.next,head.next.next] = [head.next.next,head.next]
可以这么理解,第一步在右边创建临时变量 [1,{next:1}],然后就是临时数组的一个解构,等同于 [head.next,head.next.next] = [1,{next:1}]
[1,{next:1}]
但是这里就需要注意下面的两步了
① 的执行 head.next 的值变为 1 了,这时 head 的值就为 {next:1},head 的原先的值被改变了。
head.next
{next:1}
② 再执行的时候,head.next.next 现在已经为 undefined 了,即 head.next 为 1,它不是一个对象。
head.next.next
所以最终的值变为了 {next:1};
解构(destructuring)是一种赋值语法,可从数组中提取元素或从对象中提取属性,将其值赋给对应的变量或另一个对象的属性。解构地目的是简化提取数据的过程,增强代码的可读性。有两种解构语法,分别是数组解构和对象解构,两者的区别在于解构赋值语句的左侧,前者是数组字面量,而后者是对象字面量。
在数组解构时,解构会按顺序作用于数组的元素上,也就是说,变量或对象属性要取谁的值与它所在的位置有关。
[a, b] = [1, 2]; console.log(a, b); // 1 2 [b, a] = [1, 2]; console.log(a, b); // 2 1
在经典的冒泡排序中,会交换两个值的位置,传统的做法是用一个临时变量做中转。而如果用解构的语法,那么就可以省略那个临时变量,并且写法更为简洁。
let a = 1, b = 2; /* 数组解构 */ [a, b] = [b, a]; /* 传统做法 */ let tmp = a; a = b; b = tmp;
数组解构还可以有选择性的赋值,只要在数组指定的位置上不提供元素,就能为其省去解构赋值。
[, , c] = [1, 2, 3]; console.log(c); // 3
解构赋值表达式的右侧必须是可迭代对象,否则就会报错。
[a, b] = NaN; [a, b] = Null; [a, b] = null;
另外也可以结合扩展运算符
[a, ...rest] = [1, 2, 3]; console.log(a); // 1 console.log(rest); // [2,3]
由于对象的属性没有按顺序排列,所以解构对象只会根据属性的名称是否相同来取值。
({ a, b } = { b: 1, a: 2 }); console.log(a, b); // 2,1
其实等同于
({ a: a, b: b } = { b: 1, a: 2 });
分析下它的过程:
所以匹配同名属性只是为了定位,真正被赋值的是处在属性值位置上的变量或另一个对象的属性。
看个例子就好理解了
({ a: e, b: f } = { b: 1, a: 2 }); console.log(e, b); // 2, 1
对象解构允许出现多个同名属性
({ a: e, a: f } = { b: 1, a: 2 }); console.log(e, f); // 2 2
ES6 允许对象字面量的属性名用表达式定义(即属性名可计算)
let obj = { custName: "yd" }, attr = "Name"; ({ ["cust" + attr]: value } = obj); console.log(value); // yd
数组解构和对象解构都能包含一个可供赋值的默认值。如果是数组解构并且指定位置的元素不存在或其值不存在,那么就会使用默认值。判断元素的值是否存在,只要与 undefined 做全等(===)比较,当结果为真时,表示值不存在。
[a, b = 2] = [1]; console.log(b); // 2 [a, b = 2] = [1, undefined]; console.log(b); // 2 [a, b = 2] = [1, null]; console.log(b); // null
3.2 对象解构的 1) 小点第三段代码的 console 打印的变量有误。
原文: ({ a: e, b: f } = { b: 1, a: 2 }); console.log(e, b); // 2, 1
修正: ({ a: e, b: f } = { b: 1, a: 2 }); console.log(e, f); // 2, 1
({ a: e, b: f } = { b: 1, a: 2 }); console.log(e, f); // 2, 1
2 1 {next: 1}
扫描下方二维码,收藏关注,及时获取答案以及详细解析,同时可解锁800+道前端面试题。
一、答案
二、参考解析
通过解构赋值可以交换两个变量的值,所以
[a,b] = [b,a]
,但是对象就需要注意下了。注意解构的过程,来分析下
[head.next,head.next.next] = [head.next.next,head.next]
可以这么理解,第一步在右边创建临时变量
[1,{next:1}]
,然后就是临时数组的一个解构,等同于 [head.next,head.next.next] = [1,{next:1}]但是这里就需要注意下面的两步了
① 的执行
head.next
的值变为 1 了,这时 head 的值就为{next:1}
,head 的原先的值被改变了。② 再执行的时候,
head.next.next
现在已经为 undefined 了,即head.next
为 1,它不是一个对象。所以最终的值变为了
{next:1}
;三、知识点:解构
解构(destructuring)是一种赋值语法,可从数组中提取元素或从对象中提取属性,将其值赋给对应的变量或另一个对象的属性。解构地目的是简化提取数据的过程,增强代码的可读性。有两种解构语法,分别是数组解构和对象解构,两者的区别在于解构赋值语句的左侧,前者是数组字面量,而后者是对象字面量。
3.1 数组解构
在数组解构时,解构会按顺序作用于数组的元素上,也就是说,变量或对象属性要取谁的值与它所在的位置有关。
在经典的冒泡排序中,会交换两个值的位置,传统的做法是用一个临时变量做中转。而如果用解构的语法,那么就可以省略那个临时变量,并且写法更为简洁。
数组解构还可以有选择性的赋值,只要在数组指定的位置上不提供元素,就能为其省去解构赋值。
解构赋值表达式的右侧必须是可迭代对象,否则就会报错。
另外也可以结合扩展运算符
3.2 对象解构
由于对象的属性没有按顺序排列,所以解构对象只会根据属性的名称是否相同来取值。
其实等同于
分析下它的过程:
所以匹配同名属性只是为了定位,真正被赋值的是处在属性值位置上的变量或另一个对象的属性。
看个例子就好理解了
对象解构允许出现多个同名属性
ES6 允许对象字面量的属性名用表达式定义(即属性名可计算)
3.3 默认值
数组解构和对象解构都能包含一个可供赋值的默认值。如果是数组解构并且指定位置的元素不存在或其值不存在,那么就会使用默认值。判断元素的值是否存在,只要与 undefined 做全等(===)比较,当结果为真时,表示值不存在。