本文是学习 阮一峰《ECMAScript 6 入门》 变量的解构赋值 部分的笔记。
解构(Destructing): ES6
按照一定的模式,从数组和对象中提取值,对变量进行赋值,这被称为 “解构” 。
数组的解构赋值
基本用法
可以从数组中提取值,按照对应的位置,对变量赋值;
“模式匹配”: 只要等号两边的模式相同,左边的变量就会被赋予对应的值;
|
|
1、使用嵌套数组进行解构
|
|
2、解构不成功
如果解构不成功,变量的值就等于 undefined
(等号右边的模式,只匹配等号左边的一部分)
|
|
3、不完全解构
等号左边的模式,只匹配等号右边一部分的数组,这种情况下依然可以解构成功,但是不完全解构。
|
|
4、等号右边不是数组:报错!
严格的说,应该是不可遍历的解构
|
|
对于 Set
结构(后面内容),也可以使用数组的解构赋值;
|
|
Iterator 接口
,都可以采用数组形式的解构赋值;
默认值
解构赋值允许指定默认值;
|
|
1、不生效ES6
内部使用严格相等运算符(===)
来判断一个位置是否有值。所以一个数组成员不严格等于 undefined
,默认值是不会生效的。
|
|
2、表达式
如果默认值是一个表达式,则这个表达式是惰性求值的,即只有在用到的时候,才会求值。
|
|
上面代码中,x
能取到值 (1)
,所以函数 f()
不会执行。
3、引用解构赋值的其他变量
默认值可以引用结构赋值的其他变量,但是该变量必须已经声明。
对象的解构赋值
1、与数组的不同
数组的元素是按次序排列的,变量的取值由它们的位置决定;
而对象的属性没有次序,变量必须与属性同名,才能取到正确的值;
|
|
第一个例子:前两个变量(name
和 age
),虽然和等号右边的顺序不一样,但是因为等号右边有两个同名属性,所以依然可以取到值;而最后一个变量(hobby
),等号右边不存在同名属性,所以取不到值。
第二个例子:这是对象解构赋值最完整的写法,即等号左边(hobby:interest
),其中 hobby
是匹配的模式, interest
才是变量。
等号右边(interest:“running”
), hobby
是变量的同名属性(其实是属性与匹配模式同名),“running”
是值。
看下面两个例子,更好的理解同名属性具体指的是什么。
|
|
概括一下:对象的解构赋值,首先要找到变量的同名属性,然后再赋值给对应的变量,真正被赋值的是后者,而不是前者。(比如 name:name
,真正被赋值的是后面的 name
,而不是前面的 name
)。
2、嵌套解构赋值
|
|
上面代码中,一共有三次解构赋值,先看最后一次 country:{person:{age}}
,country
和 person
在这里都是模式,不是变量,所以只有变量 age
能取到值;如果想要让模式 country
和 person
也要作为变量取到值,就要像前面两次一样。
嵌套赋值
|
|
3、指定默认值
与数组一样,默认值生效的条件是,对象的属性值严格等于 undefined
。
|
|
4、解构失败
如果解构失败,变量的值等于 undefined
。
|
|
上面第二个例子,等号左边对象 person
模式对应的变量还是一个对象,进行解构赋值时, person
等于 undefined
,再去子属性就会报错。
因此,如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,就会报错。
5、已经声明的变量用于解构赋值(Be careful!)
|
|
如果是已经声明的一个变量,用于解构赋值时,{x}
会被理解为代码块,从而发生语法错误。此时,应该要避免 {x}
被理解为代码块,可以在最外面加上一个圆括号,如第二个例子,就不会报错。
6、其他
解构赋值允许等号左边的模式之中,不放置任何变量名,虽然语法是合理的,但是毫无意义;
|
|
对象的解构赋值,可以很方便的将现有对象的方法,赋值给某个变量;
|
|
这样每次使用Math对象的对数、正弦、余弦方法时,只要直接调用 log
,sin
,cos
即可。
可以数组进行对象属性的解构,因为数组本质是特殊的对象;
|
|
上面第二行代码扩展开来其实就是:
|
|
等号右边,每一项冒号的左边其实就是数组的索引值。