变量的解构赋值

数组的解构赋值

1.基本用法
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构.
可以从数组中提取值,按照位置的对应关系对变量赋值.
本质上,这种写法属于模式匹配,只要等号两边的模式相同,左边的变量就会被赋予对应的值.

var [a, b, c] = [1, 2, 3];
var [d, ...array] = [1, 2, 3];
console.log(a);
console.log(b);
console.log(c);
console.log(d);
console.log(array); // [2, 3]

let [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo);
console.log(bar);
console.log(baz);

let [, , third] = [1, 2, 3];
console.log(third); // 3

2.如果结构不成功,变量的值就等于undefined.
另一种情况是不完全解构,即等号左边的模式只匹配等号右边数组的一部分,
这种情况下,解构依然可以成功.
如果等号的右边不是数组(或者严格的说,不是可遍历的结构),那么将会报错.

let [bar1, foo1] = [1];
console.log(bar1);  // 1
console.log(foo1);  // undefined

3.默认值
解构赋值允许指定默认值
注意,ES6内部使用严格相等运算符(===)判断一个位置是否有值,所以,如果一个数组成员
不严格等于undefined,默认值是不会生效的.

var [foo = true] = [];
console.log(foo); // true
var [x, y = 'b'] = ['a'];
console.log(x); // 'a'
console.log(y); // 'b'

var [xx, yy = 'b'] = ['a', undefined];
console.log(xx);    // 'a'
console.log(yy);    // 'b'

// 如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined
var [xxx = 1] = [undefined];
var [yyy = 1] = [null];
console.log(xxx);   // 1
console.log(yyy);   // null

// 如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候才会求值
// 因为x能取到值,所以函数f根本不会执行
function f() {
    console.log('aaa');
}
let [xxxx = f()] = [1];
// 默认值可以引用解构赋值的其他变量,但该变量必须已经声明
let [x = 1, y = x] = [];
console.log(x); // 1
console.log(y); // 1

let [xx = 1, yy = xx] = [2];
console.log(xx);    // 2
console.log(yy);    // 2

let [xxx = 1, yyy = xxx] = [1, 2];
console.log(xxx);   // 1
console.log(yyy);   // 2

let [xxxx = yyyy, yyyy = 1] = []; // ReferenceError
console.log(xxxx);  // undefined
console.log(yyyy);  // 1

对象的解构赋值

1.解构不仅可以用于数组,还可以用于对象.
对象的解构与数组有一个重要的不同,数组的元素是按次序排列的,变量的取值由它的位置决定.
而对象的属性没有次序,变量必须与属性同名,才能取到正确的值.
也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量.
真正被赋值的是后者,而不是前者.
这实际上说明,对象的解构赋值是以下形式的简写.

var { foo: foo, bar: bar } = {
    foo: 'aaa',
    bar: 'bbb'
};

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

// 如果变量名与属性名不一致,必须写成下面这样
var { foo1: baz1 } = {
    foo1: 'aaa',
    bar: 'bbb'
};
// console.log(foo1);   // Uncaught ReferenceError: foo1 is not defined
console.log(baz1);  // 'aaa'

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

2.和数组一样,解构也可以用于嵌套解构的对象

// 注意,这时p是模式,不是变量,因此不会被赋值
var obj = {
    p: [
        'hello',
        { y: 'wrold' }
    ]
};
var { p: [x, { y }] } = obj;
console.log(x); // 'hello'
console.log(y); // 'world'

// 只有line是变量,loc和start都是模式,不会被赋值
var node = {
    loc: {
        start: {
            line: 1,
            column: 5
        }
    }
};
var { loc: { start: { line } } } = node;
console.log(line);

// 嵌套赋值
let obj1 = {};
let arr = [];
({ foo: obj1.prop, bar: arr[0] } = { foo: 123, bar: true });
console.log(obj1);  // {prop:123}, obj1.prop被赋值123,所以obj1是一个对象
console.log(arr);   // [true], arr[0]被赋值为true,所以arr是一个数组
    原文作者:蛋白
    原文地址: https://segmentfault.com/a/1190000010536616
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞