ES6 2、对象的解构赋值

对象的解构赋值

  • 1、解构不仅可以用于数组,还可以用于对象
    • 2、对象的解构无关次序
    • 3、如果解构失败,变量的值等于undefined。
    • 4、对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。
    • 5、如果变量名与属性名不一致,必须写成下面这样。
    • 6、 与数组一样,解构也可以用于嵌套结构的对象。
    • 7、对象的解构也可以指定默认值
    • 8、注意点
        • (1)如果要将一个已经声明的变量用于解构赋值,必须非常小心。
        • (2)解构赋值允许等号左边的模式之中,不放置任何变量名。因此,可以写出非常古怪的赋值表达式。
        • (3)由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
  • 小结


1、解构不仅可以用于数组,还可以用于对象

let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
console.log(foo);       // "aaa"
console.log(bar);       // "bbb"
// 对象解构时,是赋予键的值

2、对象的解构无关次序

变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值

let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
console.log(foo);      // "aaa"
console.log(bar);      // "bbb"

let { baz } = { foo: 'aaa', bar: 'bbb' };
console.log(baz);     // undefined

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

3、如果解构失败,变量的值等于undefined。

let { foo } = { bar: 'baz' };
console.log(foo);  // undefined

// 上面代码中,等号右边的对象没有foo属性,所以变量foo取不到值,所以等于undefined。

4、对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。

let { log, sin, cos } = Math;
console.log(log, sin, cos);
// 上面代码的例一将Math对象的对数、正弦、余弦三个方法,赋值到对应的变量上,使用起来就会方便很多。

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

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
console.log(baz);    // "aaa"
// 此例是想将右边对象的属性foo值赋予baz,但是由于变量名与属性名不一致,直接赋值baz会等于undefined

let { first: f, last: l } = { first: 'hello', last: 'world' };
console.log(f);      // 'hello'
console.log(l);      // 'world'

​ 这实际上说明,对象的解构赋值是对象的简写形式,

let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
// 也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
console.log(baz);  // "aaa"
console.log(foo);  // error: foo is not defined

// 上面代码中,foo是匹配模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo。

6、 与数组一样,解构也可以用于嵌套结构的对象。

let obj = {
    p: [
        'Hello',
        { y: 'World' }
    ]
};

let { p: [x, { y }] } = obj;
console.log(x);     // "Hello"
console.log(y);     // "World"

注意,这时p是模式,不是变量,因此不会被赋值。如果p也要作为变量赋值,可以写成下面这样

// 例子1:
let obj = {
    p: [
        'Hello',
        { y: 'World' }
    ]
};
let { p, p: [x, { y }] } = obj;
console.log(x);     // "Hello"
console.log(y);     // "World"
console.log(p);     // ["Hello", {y: "World"}]
// 例子2:
const node = {
    loc: {
        start: {
            line: 1,
            column: 5
        }
    }
};

let { loc, loc: { start }, loc: { start: { line } } } = node;
console.log(loc);       // {start: {…}}             ——————Object {start: Object}
console.log(start);     // {line: 1, column: 5}     ————Object {line: 1, column: 5}
console.log(line);      // 1
//	上面代码有三次解构赋值,分别是对loc、start、line三个属性的解构赋值。
//	注意,最后一次对line属性的解构赋值之中,只有line是变量,loc和start都是模式,不是变量。

7、对象的解构也可以指定默认值

var { x = 3 } = { x }
console.log(x); //3

var { message: msg = 'Something went wrong' } = {};
console.log(msg);    // "Something went wrong"

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

8、注意点

(1)如果要将一个已经声明的变量用于解构赋值,必须非常小心。
// 错误的写法
let x;
{ x } = { x: 1 };//  SyntaxError: syntax error
// 上面代码的写法会报错,因为 JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。
// 只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。

{
    // 正确的写法
    let x;
    ({ x } = { x: "正确的写法 1" });
    console.log(x);
}
(2)解构赋值允许等号左边的模式之中,不放置任何变量名。因此,可以写出非常古怪的赋值表达式。
({} = [true, false]);
({} = 'abc');
({} = []);
// 上面的表达式虽然毫无意义,但是语法是合法的,可以执行。
(3)由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
let arr = ["aaa", "bbb", "ccc"];
let { 0: first, [arr.length - 1]: last } = arr;
console.log(first);     // aaa
console.log(last);      // ccc

// 上面代码对数组进行对象解构。
// 数组arr的0键对应的值是1,[arr.length - 1]就是2键,对应的值是3。

小结

对象的结构赋值,核心点是模式匹配,模式决定真正赋值的是谁。
提示:文章内容主要参考阮一峰《ECMAScript 6 入门》,更多详细内容可以去看阮老师的文章,这里做常用内容的讲解 阮一峰>>>《ECMAScript 6 入门》

你可能感兴趣的:(ECMA_javascript,es6)