变量的解构赋值
数组
-
ES6内部使用严格相等运算符(
===
),判断一个位置是否有值。所以只有一个数组成员严格等于undefined
,默认值才生效。let [x = 1] = [undefined]; x // 1 let [x = 1] = [null]; x // null
-
如果解构的默认值是一个表达式,那么这个表达式是惰性求值的,简单来说就是只有用到的时候才会求值。
-
解构默认值可以引用解构赋值的其他变量,但是这个变量必须已经声明。
对象
-
对象解构赋值和数组解构赋值的区别:
- 数据的元素是按次序排列的,变量的取值由它的位置决定。
- 对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
-
注意变量名和属性名不一致的情况
let {foo:baz}= {foo:'aaa',bar:'bbb'}; baz //"aaa" /* foo 是匹配模式 baz才是变量 真正被赋值的变量是baz 而不是foo */ let obj = {first:'hello',last:'world'}; let {first:f,last:l}=obj; f // 'hello' l // 'world'
-
默认值生效的条件是,对象的属性值严格等于
undefined
。 -
⚠️
- 如果要将已经声明的变量用于解构赋注 必须非常小心。
// 错误的写法 let x; {x}= {x:1}; // syntanxError:syntax error
以为JavaScript引擎将
{x}
理解成为一个代码块,从而发生语法错误。只有不将大括号写在行首,避免JS引擎将其解释成为代码块,才能解决这个问题。
let x; ({x}={x:1};); 正确的写法
-
解构赋值允许等号左边的模式之中,不放置任何变量名。
({} = [true, false]); ({} = 'abc'); ({} = []);
没有意义 但是语法是合法的 可以执行。
-
由于数组本质是特殊的对象,所以可以对数组进行对象属性解构。
let arr = [1, 2, 3]; let {0 : first, [arr.length - 1] : last} = arr; first // 1 last // 3
方括号这种写法,属于“属性名表达式”。
字符串
数组的对象都有一个length
属性,因此还可以对这个属性解构赋值
let {length : len} = 'hello';
len // 5
数值和布尔值
如果等号的右边是数值或者布尔值,则会先转化成对象。
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于
undefined
和null
无法转为对象,所以对它们进行解构赋值,都会报错
函数参数
function move({x = 0, y = 0} = {}) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
这个是对x,y参数进行默认值设置。
function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
这个是对函数move的参数指定默认值。
undefined
就会触发函数参数的默认值。
[1, undefined, 3].map((x = 'yes') => x); //[1,'yes',3]
圆括号问题
不能使用与括号的情况
- 变量声明语句
- 函数参数
- 赋值语句的模式
可以使用圆括号的情况
赋值语句的非模式部分
[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确
[(parseInt.prop)] = [3]; // 正确
用途
-
交换变量的值
-
从函数返回多个值
-
函数参数的定义
-
提取JSON数据
-
函数参数的默认值
-
遍历Map结构
// 获取键名 for (let [key] of map) { // ... } // 获取键值 for (let [,value] of map) { // ... }
只是想获取键 或者只是想获取值。
-
输入模块的指定方法