ES6 对象的解构赋值
对象的结构和数组有一个重要的不同,数组的元素时按照次序排序的,变量的取值是由它的位置决定的,而对象的属性没有次序,变量必须和属性同名才能取到正确的值
let { bar, foo } = {foo: 'a', bar: 'b'};
// foo = 'a'
// bar = 'b'
let { ccc } = {foo: 'a', bar: 'b'};
// ccc = undefined
如果变量名和属性名不一致
var {foo: baz} = {foo: 'a', bar: 'b'};
// baz = 'a'
let obj = { first : 'hello', last: ' world' };
let { first: f , last: l } = obj;
// f = ' hello'
// l = ' world'
注意:
// foo 是匹配模式,baz才是变量,真正赋值的是变量baz,而不是模式foo
let { foo : baz } = { foo : 'aaa', bar: 'bbb' };
// baz = 'aaa'
// foo error: foo is not defined
1.嵌套对象的结构赋值
// p是模式,不是变量,p不会被赋值
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'} ]
案例1:
var node = {
loc: { start: { line: 1, column: 5 } }
}
var { loc, loc: { start }, loc: { start: { line }}} = node;
console.log('我是loc:', loc);
console.log('我是start:', start);
console.log('我是line:', line);
// 我是loc: { start: { line: 1, column: 5 } }
// 我是start: { line: 1, column: 5 }
// 我是line: 1
注意: 只有line是变量,loc和start都是模式,不是变量
案例2: 嵌套赋值
let obj = {};
let arr = [];
({ foo: obj.prop, bar: arr[0]} = { foo: 123, bar: true})
console.log('我是obj', obj);
console.log('我是arr', arr);
// 我是obj { prop: 123 }
// 我是arr [ true ]
2.指定默认值
var { x = 10 } = {};
// x = 10
var {x, y = 20} = {x: 1};
// x = 1
// y = 20
var { x: y = 30 } = {};
// y = 30
var { x: y = 40 } = { x: 50 };
// y = 50
默认值生效条件: 对象的属性值严格等于undefined
var { x = 3 } = { x: undefined };
// x = 3
// x的属性值等于null, 不严格等于undefined,默认值不生效
var { x = 5 } = { x: null };
// x = null
结构失败:
// 如果结构失败,变量的值等于undefined
let { foo } = { baz: 'baz'};
// foo = undefined
// 报错
let {foo: {bar}} = {baz : ' baz' } ;
// 原因: 等号左边对象的foo属性对应的是一个子对象,该子对象的bar属性在结构时会报错, 此时foo是undefined,再取子属性就会报错
//报错
let temp = { baz: 'baz' };
// temp.foo.bar 报错
错误写法
// 错误写法
let x;
{x} = {x: 1};
// SyntaxError: syntax error
// 因为javaScript引擎会将{x}理解成一个代码块,从而发生语法错误,
// 只有不将大括号写在行首,避免javascript将其解释为代码块,才能解决这个问题
// 正确的写法
({x} = { x: 1});
现有的对象的解构赋值
// 将Math对象的对数,正弦,余弦三个方法赋值给对应的变量
let {log, sin, cos} = Math;
数组本质是特殊的对象,因此对数组进行对象属性结构
let arr = [1, 2, 3];
let {0: first, [arr.length - 1]: last} = arr;
// first = 1
// last = 3