ES6 之对象的解构赋值

基本用法

ES6 允许对象也能使用解构赋值

let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

对象的解构中对象的属性没有次序,变量必须与属性同名,才能取到正确的值

let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined

上面代码的第一个例子,等号左边的两个变量的次序,与等号右边两个同名属性的次序不一致,但是对取值完全没有影响
第二个例子的变量没有对应的同名属性,导致取不到值,最后等于 undefined

如果变量名与属性名不一致,必须写成下面这样

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

上面代码中,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"}]

上面代码有三次解构赋值,分别是对 p、x、y 三个属性的解构赋值
最后一次对 y 属性的解构赋值之中,只有 y 是变量,p 和 x 都是模式

特殊解构赋值

由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。

let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first // 1
last // 3

数组 arr 的 0 键对应的值是 1,[arr.length - 1] 就是 2 键,对应的值是 3
方括号这种写法,属于“属性名表达式”(ES6 新特性,本文不作详解)

默认值

var {x = 3} = {};
x // 3

var {x, y = 5} = {x: 1};
x // 1
y // 5

var {x: y = 3} = {};
y // 3

var {x: y = 3} = {x: 5};
y // 5

var { message: msg = 'Something went wrong' } = {};
msg // "Something went wrong"

默认值生效的条件是,对象的属性值严格等于 undefined

var {x = 3} = {x: undefined};
x // 3

var {x = 3} = {x: null};
x // null

上面代码中,属性 x 等于 null,因为 null 与 undefined 不严格相等,所以是个有效的赋值,导致默认值3不会生效

错误的解构

如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错

// 报错
let {foo: {bar}} = {baz: 'baz'};

如果要将一个已经声明的变量用于解构赋值,需要注意

// 错误的写法
let x;
{x} = {x: 1};
// SyntaxError: syntax error

上面代码的写法会报错,因为 JavaScript 引擎会将 {x} 理解成一个代码块,从而发生语法错误

// 正确的写法
let x;
({x} = {x: 1});

本文转载自:http://es6.ruanyifeng.com/#docs/destructuring#对象的解构赋值 并进行整理

除特殊说明外本人博客均属原创,转载请注明出处:http://blog.johnhan.cn/blog_1013.html
鄂ICP备17018604号-1  鄂公网安备42060702000030号