摘自《ES6标准入门(第三版)》:
对象的解构赋值是下面形式的简写:
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' }
也就是说,对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量。真正被赋值的是后者,而不是前者。
let { foo: baz } = { foo: 'aaa', bar: 'bbb' }
baz // 'aaa'
foo // error: foo is not defined
上面的代码中,foo 是匹配的模式,baz 才是变量。真正被赋值的变量是 baz,而不是模式 foo。
与数组一样,解构也可以用于嵌套结构的对象。
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
p // ['Hello', { y: 'World' }]
还一个例子:
var node = {
loc: {
start: {
line: 1,
column: 5
}
}
}
var { loc, loc: { start }, loc: { start: { line } } } = node
line // 1
loc // Object {start: Object}
start // Object {line: 1, column: 5}
上面的代码有三次解构赋值,分别是 loc、start、line三个属性的解构赋值。需要注意的是,最后一次对 line 属性的解构赋值之中,只有 line 是变量,loc 和 start 都是模式,不是变量。
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于 undefined 和 null 无法转对象,所以对它们进行解构赋值时都会报错。
let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError