变量的解构赋值

变量的解构赋值

  • 数组的解构赋值

    let [a, b, c] = [1, 2, 3];
    本质:这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值;如果解构不成功值为undefined
    不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。

    let [foo, [[bar], baz]] = [1, [[2], 3]];
    foo // 1
    bar // 2
    baz // 3

    let [ , , third] = ["foo", "bar", "baz"];
    third // "baz"

    let [x, , y] = [1, 2, 3];
    x // 1
    y // 3

    let [head, ...tail] = [1, 2, 3, 4];
    head // 1
    tail // [2, 3, 4]

    let [x, y, ...z] = ['a'];
    x // "a"
    y // undefined
    z // []

  1. 默认值:如果一个数组成员不是严格等于undefined,默认值不会生效

    let [foo = true] = [];
    foo // true
    let [x, y = 'b'] = ['a']; // x='a', y='b'
    let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
    let [x = 1] = [undefined];
    x // 1
    let [x = 1] = [null];
    x // null

  • 对象的解构赋值
  1. 注意:对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

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

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

  2. 对象解构赋值的本质形式

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

  3. 嵌套结构的对象解构

    var node = {
    loc: {
    start: {
    line: 1,
    column: 5
    }
    }
    };

    var { loc, loc: { start }, loc: { start: { line }} } = node;
    line // 1
    loc // Object {start: Object}
    start // Object

  4. 对象解构的默认值;严格等于undefined时,默认值生效

    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"
    var {x = 3} = {x: undefined};
    x // 3
    var {x = 3} = {x: null};
    x // null

  • 字符串的解构赋值:此时,字符串被转换成了一个类似数组的对象。

    const [a, b, c, d, e] = 'hello';
    a // "h"
    b // "e"
    c // "l"
    d // "l"
    e // "o"
    //还可以对属性进行解构赋值
    let {length : len} = 'hello';
    len // 5

  • 数值和布尔值的解构赋值:如果等号右边是数值和布尔值,则会先转为对象。

    let {toString: s} = 123;
    s === Number.prototype.toString // true
    let {toString: s} = true;
    s === Boolean.prototype.toString // true
    解构的规则只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

    let { prop: x } = undefined; // TypeError
    let { prop: y } = null; // TypeError

  • 函数参数的解构赋值及默认值

    function move({x = 0, y = 0} = {}) {
    return [x, y];
    }

    move({x: 3, y: 8}); // [3, 8]
    move({x: 3}); // [3, 0]
    move({}); // [0, 0]
    move(); // [0, 0]
    另一种写法,结果不一样:

    function move({x, y} = { x: 0, y: 0 }) {
    return [x, y];
    }

    move({x: 3, y: 8}); // [3, 8]
    move({x: 3}); // [3, undefined]
    move({}); // [undefined, undefined]
    move(); // [0, 0]
    原因:上面代码是为函数move的参数指定默认值,而不是为变量x和y指定默认值,所以会得到与前一种写法不同的结果。

  • 变量解构赋值的用途

  1. 交换变量的值

    let x = 1;
    let y = 2;

    [x, y] = [y, x];

  2. 从函数返回多个值

    // 返回一个数组
    function example() {
    return [1, 2, 3];
    }
    let [a, b, c] = example();
    // 返回一个对象
    function example() {
    return {
    foo: 1,
    bar: 2
    };
    }
    let { foo, bar } = example();

  3. 提取JSON数据

    let jsonData = {
    id: 42,
    status: "OK",
    data: [867, 5309]
    };

    let { id, status, data: number } = jsonData;

    console.log(id, status, number);
    // 42, "OK", [867, 5309]

posted @ 2017-07-19 11:06  YFIFE  阅读(176)  评论(0)    收藏  举报