第三章 变量的解构赋值
-
数组的解构赋值
也就是在ES6里面允许对变量进行模式匹配来赋值类似
let [a, b, c] = [1, 2, 3];
,但是如果解构不成功的话值就是undefined。像let [foo] = [];
。当只有部分匹配成功的时候,匹配成功的与没有匹配成功的不会干扰也就是如果有一部分没有匹配成功也不会影响全部的匹配。当然当“=”右边的不是数组(没有interator借口的类型)的时候就不能这样做。我感觉之所以这样是因为没有interator接口的话就不能遍历访问。-
默认值
解构赋值允许指定默认值。也就是可以在定义时赋值说白了就是在“=”的左边赋值,但是这样的有个要求那就是被赋值的变量必须严格等于undefined。
需要注意的是
let [x, y = 'b'] = ['a', undefined];
这样的一段代码其实等于let [x,y]=['a',undfined]; y='b'
也就是说等号右边的会先赋值,但是要默认赋值的话变量必须严格等于undefined。所以let [x = 1] = [null];
这一段代码就是不成功的。如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。也就是说如果有赋值的话就不会用表达式了
默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
-
-
对象的解构赋值
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变 量。真正被赋值的是后者,而不是前者。也就是对象的解构体赋值是先在等号的右边找到一个属性然后再左边找与之相同的属性然后赋值。
let {foo} = {bar: 'baz'};
这个样子就是不行的因为右边没有foo这个属性所以foo为undefined。嵌套对象赋值:
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
与上面的对象解构赋值一样的原理。但是嵌套对象赋值时要注意子属性的父属性是要给的不然会报错就不是undefined问题了例如:let {foo: {bar}} = {baz: 'baz'};
因为bar的父属性没有给出来所以直接给bar赋值是不行的。对象的解构赋值可以取到继承的属性。
-
默认值
和数组的默认值一样,同样是赋值的属性必须等于undefined。
注: 因为JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。像这样{x}={x:“a”};。这样就是错的。所以要用(({x} = {x: 1});)。
-
-
字符串的解构赋值
字符串在解构赋值时会转换为一个类似数组的对象。也就是可以
let {length : len} = 'hello';
因为‘hello’被转化为一个类似数组的对象所以也有了length属性赋值就可以成功了。 -
数值和布尔值的解构赋值
也是把等号右边转换为对象再赋值。如果碰到无法转换的就会报错
-
函数参数的解构赋值
函数参数的结构赋值也就是把等号右边放到了函数的参数里面。这个时候也可以默认赋值但是由于惰性求值的原因如果传入的参数不是undefined都不会用到默认值,只有在参数是undefined时才是默认值。
-
圆括号问题
变量声明语句不能用圆括号因为它们都是变量声明语句,模式不能使用圆括号。
函数参数不能用圆括号,本质上也是变量声明。
赋值语句的模式不能用圆括号。也就是等于号的左边。
可以使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括号
-
用途
- 交换变量的值(不用像以前原因用一个中间变量)
- 从函数返回多个值(返回一个数组然后解构赋值出来)
- 函数参数的定义 (将参数和变量名对应)
- 提取 JSON 数据
- 函数参数的默认值(可以给函数参数默认值,增加容错性)
- 输入模块的指定方法