1.对象的解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
以前,为变量赋值,只能直接指定值。
let a=1
let b=4
ES6写成这样:
let [a,b,c]=[1,2,3]
let [foo, [[bar], baz]] = [1, [[2], 3]]
let [ , , third] = ["foo", "bar", "baz"]
以及这样:
'...'是语法糖,意思为合并
let [apple,...fruit]=[1,2,3,4]
fruit//[2,3,4]
let [x,y,...z]=['a']
x//a
y//undefined
z//[]
如果解构不成功,变量的值就等于undefined
let [foo]=[]
let [bar,foo]=[i]
以上的foo都是解构不成功,返回undefined
本质上,只要等号左右两边的模式相同,左边的变量就会被赋予对应的值。
下列就是左右两边模式不相同的,就会报错
// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
解构赋值允许指定默认值
let [foo=1]=[]
foo//1
赋值的权重比默认值的大,undefined除外
let [a,b='喵']=['hhh',undifined]
b//喵
let [a,b=1]=[11,2]
console.log(b)//2
let [a=1]=[null]
a//null
默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
let [x=y,y=1]=[]
//ReferenceError: y is not defined
2.对象的解构赋值
let {foo,bar}={foo:'aaa',bar:'bbb'}
foo//aaa
bar//bbb
对象的解构赋值与数组有一个很大的不同,数组的赋值必须按照顺序,但是对象不需要按照顺序,变量名和属性名相同即可
let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined
如果解构失败,返回undefined
let {foo} = {bar: 'baz'};
foo // undefined
如果变量名与属性名不一致,可以写成这样:
let {foo:baz}={foo:'aaa',bar:'bbb'}
baz// 'aaa'
let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'
也就是说,对象的解构赋值是内部的机制,是先找到同属性名,然后再赋值给对应的变量。真正被赋值的是后者,而不是前者。
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
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是模式,不是变量,如果要写成变量要写成这种:
let obj = {
p: [
'Hello',
{ y: 'World' }
]
};
let { p, p: [x, { y }] } = obj;
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]
下面是另一个例子
const node = {
loc: {
start: {
line: 1,
column: 5
}
}
};
let { loc, loc: { start }, loc: { start: { line }} } = node;
line // 1
loc // start: {line: 1, column: 5}
start // column: 5 line: 1
注意:只有line是变量,loc和start都是模式
参考:ECMAScript6入门 作者:阮一峰