美文网首页
小记3 - 1解构赋值:更高效的提取变量 - 解构数组

小记3 - 1解构赋值:更高效的提取变量 - 解构数组

作者: ilily | 来源:发表于2019-12-18 14:25 被阅读0次

    背景:解构(destructuring)有何用?

    let heros   =   {                               
              no1:  "吕布",                               
              no2:  "张飞",
              weapons:  [ "刀","剑","弓箭"]     
    };
    //  从对象中提取数据
     let lb = heros.no1,  zs = heros.no2, weapons = heros.weapons;
    

    想象一下,若heros中有100万个变量需要提取处理呢?若 是多层嵌套的数据结构呢?可能会为了一点数据而挖掘整个结构,做大量低效重复的工作。

    解构赋值

    解构赋值--使得把数据结构分解为更小的部分时,提取数据会变得更容易,更高效。
    解构赋值语法是一种 Javascript 表达式。解构使用的语法--就是对象与数组的字面量语法。--按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

    基本原则如下:

    数组的元素是按次序排列的,变量的取值由它的位置决定;
    对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

    数组的解构赋值

    1 变量声明并赋值时的解构 或者先声明变量再赋值
    let  foo = ["one", "two", "three"];
    let  [m, n, three] = foo;
    console.log(m); // "one"
    console.log(n); // "two"
    console.log(three); // "three"
    //-或者
    let [foo, [[bar], baz]] = [1, [[2], 3]];
    console.log(foo); // 1
    console.log(bar); // 2
    console.log(baz); // 3
    
    
    //先声明再赋值
    let a, b;
    [a, b] = [1, 2];
    

    注意1:在使用 var 、 let 、 const 进行数组解构时,必须提供初始化 器(即等号 右边的值)

    const [a ,b];
    let [d,e];
    // Uncaught SyntaxError: Missing initializer in destructuring declaration
    

    注意2:如果解构不成功,变量的值就等于undefined。

    let [foo] = [];
    let [bar, foo] = [1];
    //以上两种情况都属于解构不成功,foo的值都会等于undefined。
    

    注意3:不完全解构-等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

    let [x, y] = [1, 2, 3];//     x//1    y //2
    let [a, [b], d] = [1, [2, 3], 4];//     a //1   b // 2  d // 4
    

    注意4:解构报错--如果等号的右边不是数组(或者严格地说,不是可遍历的结构,不具备 Iterator 接口),那么将会报错。

    // 报错
    let [foo] = 1;
    let [foo] = false;
    let [foo] = NaN;
    let [foo] = undefined;
    let [foo] = null;
    let [foo] = {};
    
    2 忽略某些值,只对感兴趣值解构
    let [ , , third] = ["foo", "bar", "baz"];  //逗号-, 为数组前面的项提供的占位符
    console.log(third);  // "baz"
    
    3 默认值

    ES6 解构内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。

    const [a=5, b=7] = [1];
    console.log(a); // 1
    console.log(b); // 7  --默认值生效
    
    let [x = 1] = [undefined];
    x // 1   --默认值生效
    let [x = 1] = [null];
    x // null
    

    注意1:如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。

    function f() {
        console.log('aaa');
    }
    let [x = f()] = [1];  //因为x能取到值,所以函数f根本不会执行。
    
    //上面的代码其实等价于下面的代码。
    let x;
    if ([1][0] === undefined) {
      x = f();
    } else {
      x = [1][0];
    }
    

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

    let [x = 1, y = x] = [2];    // x=2; y=2
    let [x = y, y = 1] = [];     // ReferenceError: y is not defined 
    //--因为x用y做默认值时,y还没有声明
    
    4 剩余项 (...) -- 将剩余数组赋值给一个变量(数组)

    当解构一个数组时,可以使用剩余模式,将数组剩余部分赋值给一个变量。

    var [a, ...b] = [1, 2, 3];
    console.log(a); // 1
    console.log(b); // [2, 3]   --注意,这是个数组
    

    注意:如果剩余元素右侧有逗号,会抛出 SyntaxError因为剩余元素必须是数组的最后一个元素,之后不能再有逗号,否则就是语法错误。

    var [a, ...b,] = [1, 2, 3];
    // SyntaxError: rest element may not have a trailing comma
    

    应用1::若要取出特定项 并要求保留剩余的值,则剩余项是非常有用的。
    应用2:方便地克隆数组在JS中是个明显被遗漏的功能。
    在ES5中常用的concat()方法来克隆数组 (方便简单);在ES6中,使用剩余项的语法克隆数组(小技巧)

    //  在   ES5 中克隆数组 
    let colors  =   [   "red",  "green",    "blue"  ]; 
    let clonedColors    =   colors.concat();
    colors[2]   = "skyblue";
    console.log(clonedColors);      //"[red,green,blue]"
    

    concat()方法本意是合并两个数组,但不使用任何参数来调用此方法,会获得原 数组的一个克隆品。

    //  在ES6中,使用剩余项的语法克隆数组 ,达到上述同样效果
    let colors  =   [   "red",  "green",    "blue"  ]; 
    let [   ...clonedColors ]   =   colors;
    colors[2]   = "skyblue";
    console.log(clonedColors);      //"[red,green,blue]"
    
    5 嵌套的数组 解构

    在整个解构模式中插入另一 个数组模式,解构操作会下行到 嵌套的数组中。可以使用任意深 度的数组嵌套解构。

    let colors = [  "red",[ "green", "lightgreen" ],    "blue"  ];
    let [   firstColor, [   secondColor ]   ]   =   colors;
    console.log(firstColor);    //  "red" 
    console.log(secondColor);  //   "green" 
    

    应用篇

    交换变量 - 在一个解构表达式中可以轻松交换两个变量的值。
    //在 ES5 中互换值需要使用第三个变量作为临时变量:
     let    a = 1, b = 2, tmp;
     tmp    =a ;  a = b;  b = tmp;
    console.log(a); //  2 
    console.log(b); //  1
    
    //  在   ES6 中互换值 
    let a = 1, b    =   2;
    [   a,  b   ]   =   [   b,  a   ];
    console.log(a); //  2 
    console.log(b);       //1
    
    解析一个从函数返回的数组

    从一个函数返回一个数组是十分常见的情况。解构使得处理返回值为数组时更加方便。

    function f() {
      return [1, 2];
    }
    let a, b; 
    [a, b] = f(); 
    console.log(a); // 1
    console.log(b); // 2
    

    总结

    本质上,解构赋值这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
    数组的元素是按次序排列的,变量的取值由它的位置决定;

    相关文章

      网友评论

          本文标题:小记3 - 1解构赋值:更高效的提取变量 - 解构数组

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