美文网首页
变量的解构赋值

变量的解构赋值

作者: Kris_lee | 来源:发表于2017-10-25 17:29 被阅读16次

    es6-2 (变量的解构赋值)

    本文以及之后的文章都是参考
    阮一峰ES6入门
    ,记录下作为笔记。

    数组的解构赋值

    对象的解构赋值

    字符串的解构赋值

    数值和布尔值的结构赋值

    函数参数的结构赋值

    圆括号问题

    用途

    1 .数组的解构赋值

    let a = 1;
    let b = 2;
    let c = 3;
    

    ES6允许写成下面这样

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

    eg:

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

    如果解构不成功,变量的值就等于undefined.
    事实上,子要某种数据结构具有Iterator接口,都可以采用数组形式的解构赋值

    function* fibs() {
      let a = 0;
      let b = 1;
      while (true) {
        yield a;
        [a, b] = [b, a + b];
      }
    }
    
    let [first, second, third, fourth, fifth, sixth] = fibs();
    sixth // 5
    

    上面代码中,fibs是一个Generator函数,原生具有Iterator接口,解构赋值回一次从这个接口获取值。

    默认值
    let[x=1] = [undefined];
    x //1
    let [x = 1] = [null]
    x //null
    

    上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined
    如果默认值是一个表达式,那么这个表达式是惰性求值,即只有在用到的时候,才会求值。

    function f(){
    console.log('aaa')
    }
    let [x=f()] = [1]
    

    上面代码中,因为x能取到值,所以函数f根本不会执行,上面的代码其实等价于下面的代码。

    let x;
    if([1][0] === undefined){
    x = f()
    }else{
        x = [1][0] 
    }
    

    默认值可以引用结构赋值的其他变量,但该变量必须已经声明。

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

    上面最后一个表达式之所以回报错,是因为x用到默认值y时,y还没有声明

    对象的结构赋值

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

    对象的黑狗与数组有一个重要的不同,数组的元素是俺次序排列的,变量的取值由它的未知决定而对象的属性没有次序,变量必须与属性同名,才能渠道正确的值

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

    也就是说,对象的结构赋值的内部机智,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者
    与数组一样,结构也可以用于嵌套结构的对象。

    let obj = {
        p:[
        'hello',
        {y:'world'}
        ]
    }
    
    let {p:[x,{y}]} = obj;
    console.log(x+'  '+y);
    console.log(obj.p[0]);
    console.log(obj.p[1].y);
    

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

    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"
    

    如果要将一个已经声明的变量用于解构赋值,必须非常小心

    函数的参数的解构赋值
    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指定默认值,所以会得到与前一种写法不同的结果。

    undefined就会触发函数参数的默认值。

    let arr = [1,undefined,4];
    arr.map((x = 'yes')=>{
        console.log(x);
    })
    

    圆括号问题。

    解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道。

    由此带来的问题是,如果模式中出现圆括号怎么处理。ES6 的规则是,只要有可能导致解构的歧义,就不得使用圆括号。

    但是,这条规则实际上不那么容易辨别,处理起来相当麻烦。因此,建议只要有可能,就不要在模式中放置圆括号。

    用途。

    • 交换变量的值
    let x = 1;
    let y = 2;
    [x, y] = [y, x];
    
    • 从函数返回多个值
        // 返回一个数组
        
        function example() {
          return [1, 2, 3];
        }
        let [a, b, c] = example();
        
        // 返回一个对象
        
        function example() {
          return {
            foo: 1,
            bar: 2
          };
        }
        let { foo, bar } = example();
    
    • 函数参数的定义

        // 参数是一组有次序的值
        function f([x, y, z]) { ... }
        f([1, 2, 3]);
        
        // 参数是一组无次序的值
        function f({x, y, z}) { ... }
        f({z: 3, y: 2, x: 1});
      
    • 提取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]
      
    • 函数参数的默认值

        jQuery.ajax = function (url, {
          async = true,
          beforeSend = function () {},
          cache = true,
          complete = function () {},
          crossDomain = false,
          global = true,
          // ... more config
        }) {
          // ... do stuff
        };
      
    • 遍历Map结构

        const map = new Map();
        map.set('first', 'hello');
        map.set('second', 'world');
        
        for (let [key, value] of map) {
          console.log(key + " is " + value);
        }
      

      如果只想获取键名,或者只想获取键值,可以写成下面这样。

        // 获取键名
        for (let [key] of map) {
          // ...
        }
        
        // 获取键值
        for (let [,value] of map) {
          // ...
        }   
      
    • 输入模块的指定方法

        const { SourceMapConsumer, SourceNode } = require("source-map");

    相关文章

      网友评论

          本文标题:变量的解构赋值

          本文链接:https://www.haomeiwen.com/subject/ywxcpxtx.html