数组的结构赋值
基本用法
- ES6允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,称为解构。只要等号两边的模式相同,左边的变量就会被赋予对应的值。
-
let [foo,[[bar],baz]]=[1,[[2],3]]; foo //1 bar //2 baz //3 let [ , ,third]=["foo","bar","baz"] third //"baz"
默认值
- 解构赋值允许指定默认值。ES6内部使用严格相等运算符(===)判断一个位置是否有值。如果一个数组成员不严格等于undefined,默认值不会生效。
let[x,y='b']=['a']; //x='a',y='b'
let[x,y='b']=['a',undefined]; //x='a',y='b'
//如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。
let [x=1]=[null];
x //null
如果默认值是一个表达式,那么这个表达式是惰性求值的,即中只有在用到时才会求值
function f(){
console.log('aaa');
}
let[x=f()]=[1];
//x能取到值,所以函数f根本不会执行。等价的代码如下
let x;
if([1][0]===undefined){
x=f();
}else{
x=[1][0];
}
- 默认值可以引用解构赋值的其他变量,但该变量必须已经声明
对象的解构赋值
- 对象的解构与数组有所不同,对象的属性没有次序,变量必须与属性同名才能取到正确的值
let {bar,foo}={foo:"aaa",bar:"bbb"};
foo //"aaa"
bar //"bbb"
let{ baz}={foo:"aaa",bar:"bbb"};
baz undefined
- 对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量。
//foo是匹配的模式,baz才是变量。真正被赋值的是变量baz
let{foo:baz}={foo:"aaa",bar:"bbb"};
baz //"aaa"
foo //error:foo is not defined
- 解构可用于嵌套解构的对象
let obj={
p:{
'Hello',
{y:'world'}
}
};
let{p:[x,{y}]}=obj;
x //"Hello"
y //‘world"
//以上代码这种的p是模式,不是变量,英雌不会被赋值。如果p也要作为变量赋值,可以写成以下形式
let obj={
p:{
'Hello',
{y:'world'}
}
};
let{p,p:[x,{y}]}=obj;
x //"Hello"
y //‘world"
//loc:{start:{line}},loc和start都是模式,只有line是变量,所以对应的是node中line值为1。
const node = {
loc: {
start: {
line: 1,
column: 5
} }};
let { loc, loc: { start }, loc: { start: { line }} } = node;
line // 1
loc // Object {start: Object}
start // Object {line: 1, column: 5}
- 已经声明的变量用于解构赋值,必须十分小心。
//下面的例子中错误的原因是{x}被认为是一个块级作用域,导致解构失败,我们在使用解构要尽量避免这种大括号直接在行首的情况
// 错误的写法
let x;
{x} = {x: 1};
// 正确的写法
let x;
({x} = {x: 1});