zoukankan      html  css  js  c++  java
  • 变量的解构赋值--ES6

    1. 数组的解构赋值

    基本用法

    let [a, b, c] = [1, 2, 3];

    let [a,,c] = [1,2,3];

    let [a,...b] = [1,2,3]; // a=1; b=[2,3]

    // set 结构也可以
    let [x, y, z] = new Set(['a', 'b', 'c']);

    // Iterator 接口的也可以
    function* fibs(){
      yield 1;
      yield 2;
      yield 3;
      yield 4
    }

    let [first, second, third] = fibs();
    third // 3

    默认值
    let [a=2] = [1];

    若值为全等 undefined, 则才为默认值
    let [a=2] = [undefined]; // a=2
    let [a=2] = [null]; //a = null
    let [a=2] = null; // 报错, 如果模式不是数组, 因为会两边不匹配
    let [a=2] = undefined; // 报错

    若默认值是一个表达式, 那么这个表达式是 惰性求值, 只有用到的时候才会求值
    function f(){
      console.log('fffff'); // 这里不会执行
    }
    let [a=f()] = [1];
    a; // 1

    // 相当于执行了下面
    if( [1][0] === undefined ){
      a = f();
    }else{
      a = 1;
    }

    2. 对象的解构赋值

    let {a=3} = {a: 1};
    a; // 1

    其实相当于:
    let {a: a=3} = {a: 1};
    // 有点类似于下面的写法
    let _temp = {a: 1};
    let a = _temp.a || 3;

    解构赋值给空数组和空对象

    let [a=3] = {} // ?会报错: Uncaught TypeError: undefined is not a function
    let {a=3} = [] // 正确 a = 3;

    下面的两种写法是一样的, 数组元素是按次序, 变量的取值由它对应的属性名决定。
    let {a, b} = {a: 1, b: 2}
    let {b, a} = {a: 1, b: 2}

    如果变量名与属性名不一致, 写成下面这样, a 是匹配的模式, c 才是变量
    let {a:c} = {a: 1, b: 2}
    c; //1

    说明对象的解构赋值是下面形式:
    let {a, b} = {a: 1, b: 2};
    // 等价于下面
    let {a:a, b:b} = {a: 1, b: 2}

    对象也可以进行嵌套
    let {a: [{b}, c]} = {a: [{b: 2}, 3]}

    a; // undefined
    b; // 2
    c; // 3

    嵌套赋值例子:
    let obj = {};
    let arr = [];

    ( {a: obj.q, b: arr[0]} = {a: 1, b: 2} );
    obj; // {q: 1}
    b; // [2]


    解构也可以指定默认值, 也是必须 === undefined
    let { a=3 } = {a: 1};
    a; //1

    let { a=3 } = {a: null};
    a; //null

    let {a=4} = {a: undefined};
    a; // 4

    如果解构失败,变量的值等于undefined
    let {a} = {b: 2};
    a; // undefined


    如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
    // 报错
    let {foo: {bar}} = {baz: 'baz'};
    相当于:
    let _temp = {baz: 'baz'};
    {bar} = _temp.foo;
    bar = _temp.foo.bar;

    已经声明的变量用于解构赋值, 会将 {x}理解成一个代码块 而不是一个语句, 所以要有括号
    let x;
    {x} = {x: 1}; // Uncaught SyntaxError: Unexpected token =

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

    {foo} = {foo: 1}; // 若不用let 也是正确的, foo 直接挂载到 window 下


    3. 字符串的解构赋值
    // 字符串转换成 类似数组
    const [a,b] = 'hello';
    a; // h
    b; // e

    // 字符串类似对象, 它有一个length 的属性
    let {length : len} = 'hello';


    4. 数值和布尔值的解构赋值
    数值和布尔值都会转好成 包装对象

    // 相当于s = 123.toStirng
    let {toString: s} = 123;

    // 相当于 s = true.toString
    let {toString: s} = true;

    解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。
    由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

    let {a: 1} = null; // error
    let {a: 1} = undefined; // error


    5. 函数参数的解构赋值
    function add([x, y]){
      return x + y;
    }

    add([1, 2]); // 3
    相当于 [x, y] = [1, 2];

    对于 map
    // [5, 10]
    [1, 2].map( (a) => a *5 );

    // [3, 7]
    [[1,2], [3,4]].map( ([a,b]) => a+ b )


    函数参数的解构也可以使用默认值。

    // 只有当传递的参数为undefined 或不传参数的时候, 才会执行 {a, b} = {a: 1, b: 3}
    function move({a, b} = {a: 1, b: 2}){
      return [a,b]
    }
    move({a: 3, b: 4}); // [3, 4];                     等价 {a, b} = {a: 3, b: 4}
    move({a: 3});       // [3, undefined];             等价 {a, b} = {a: 3}
    move({});           // [undefined, undefined];     等价 {a, b} = {}
    move([]);           // [undefined, undefined];     等价 {a, b} = []
    move(null);         // 报错;                        等价 {a, b} = null
    move();             // [1, 2];                     等价 {a, b} = {a: 1, b: 2}
    move(undefined);    // [1, 2];                     等价 {a, b} = {a: 1, b: 2}
    
    // 同上面道理
    function move({x = 0, y = 0} = {x: 100, y: 200}) {
      return [x, y];
    }
    
    move({x: 3, y: 4});   // [3, 4]
    move({x: 3});         // [3, 0]
    move({});             // [0, 0]
    move();               // [100, 200]

    undefined就会触发函数参数的默认值。
    [1, undefined, 3].map( (a = 2) => a ); // [1, 2, 3]

    6. 圆括号的问题
    使用圆括号的情况

    赋值语句并且非模式部分,可以使用圆括号。
    ({ p: (d) } = {p: 3}); // 正确, 这里d是非模式, p是模式, 最后 d = 3
    let ({ p: (d) } = {}); // 错误, 因为是声音语句

    [(b)] = [3]; // 正确, 说明这个b是非模式部分, 有点类似于 [0:(b)] = [3], 直接这么写会报错
    ({(a)} = {a: 3}); // 错误, 说明是这么执行 {(a): a} = {a: 3}; 括号加在了 a的模式部分


    7.用途

    1) 交换变量的值
    let x=1;
    let y=2;
    [x,y] = [y,x];

    2) 从函数返回多个值
    function f(){
      return {
        a: 1,
        b: 2
      }
    }

    let {a, b} = f();

    function f(){
      return [2, 3]
    }
    let [a, b] = f();

    3) 函数参数的定义
    function f([x, y, z]){
      console.log(arguments[0]); // [1,2,3]
      console.log(x, y, z);
    }
    f([1,2,3]);

    function f({x, y, z}){
      console.log(arguments[0]); // arguments[0] 其实就是 {x: 1, y:2, z: 3}
      console.log(x, y, z); // x = 1, y = 2, z = 3;
    }
    f({x: 1, y: 2, z: 3});

    4) 提取JSON数据
    let o = {
      a: 1,
      b: 2
    }

    let {a, b} = o;

    5) 函数参数的默认值
    function f({x = 2, y = 3}){
      console.log(x, y);
    }
    f({});
    f(); // error, 必须至少传入空对象, 否则会报错

    6)遍历Map结构
    var map = new Map();
    map.set('first', 'hello');
    map.set('second', 'world');

    for(let item of map){
      console.log(item); // item 分别输出 ["first", "hello"], ["second", "world"]
    }

    所以可以写成:
    for(let [key, value] of map){
      cnosole.log(key, value);
    }

    // 获取key 的值
    for( let [key] of map){
      console.log(key);
    }

    // 获取value 的值
    for( let [, value] of map){
      console.log(value);
    }

    7)输入模块的指定方法
    const {a, b} = require('./test2')
    import {a, b} from './test2';

  • 相关阅读:
    python2文件转换为exe可执行文件
    pycharm下 os.system os.popen执行命令返回有中文乱码
    python 虚拟环境
    git commit之后,想撤销commit
    Android Dialog使用举例
    Builder模式在Java中的应用(转)
    AngularJS promise()
    给你一个承诺
    AngularJs 用户登录验证模块(demo)参考总结
    推荐 15 个 Angular.js 应用扩展指令(参考应用)
  • 原文地址:https://www.cnblogs.com/zhengming2016/p/7068599.html
Copyright © 2011-2022 走看看