• ES2015中的解构赋值


    ES2015中允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,被称为”解构(Destructering)“。

    以前,为变量赋值,只能指定值。

     1     /**
     2      * 以前,为变量赋值,只能直接指定值
     3      * **/
     4     let a = 1;//第一种:变量赋值
     5     let b = 2;
     6     let c = 3;
     7     /**
     8      * 现在ES2015允许这样:数组和对象
     9      * **/
    10     let [a,b,c] = [1,2,3];//第二种:数组的解构赋值
    11     let {a,b,c} = {
    12         a:1,
    13         b:2,
    14         c:3
    15     };//第三种:json对象解构赋值

    本质上,后两种通过解构赋值的写法属于”模式匹配“,只要判定了等号两边的模式相同(解构),左边的变量就会被赋予对应的值即赋值。

    数组的解构赋值

    上面例子第二种就是数组解构赋值,这是刚好完全解构的情况,还有两种不完全解构的情况:

     1   /**
     2      * 不完全解构的情况
     3     */
     4     {
     5         let [a,b,c] = [1,2];//c的值:undefined
     6         console.log(a,b,c);//1 2 undefined
     7     }
     8 
     9     {
    10         let [a,b] = [1,2,3];//右侧多了一个3
    11         console.log(a,b);//1,2
    12     }
    13 
    14     {
    15         let [,,c] = [1,2,3];//c 3
    16         console.log(c);//3
    17     }
    18     /**
    19      * 由此例子可以看到当左侧的c没有解构成功时(即右侧的数据结构没有与之对应的部分),那么这个变量的值为undefined
    20      * 那么这个变量的值为undefined,我们知道某个值为undefined的时候存在两种情况:
    21      * 一种是生命了没有赋值
    22      * 另一种是显示赋值为undefined
    23      * **/
    1 {
    2         const [d] = [];
    3         console.log(d);//undefined
    4         //没有解构成功的变量会被显式赋值为undefined
    5 }

    当数组内部有嵌套时,解构依然能正常进行:

    1 {//可以嵌套
    2    let [a,[b,c],d] = [1,[2,3],4];
    3    console.log(a,b,c,d);
    4 }

    除此之外还允许为解析解构设定默认值,即变量在解构后没有被赋到值(严格来说,应该被赋值为undefined)的情况下允许赋予变量某个默认值:

     1        let [foo = true] = [];
     2        console.log(foo);//true
     3 
     4        let [x,y="bbb"] = ["a"];
     5        console.log(x,y);//a bbb
     6 
     7        let [x,y= "b"] = ["a",undefined];
     8        console.log(x,y);//a b
     9 
    10        let [x = 4] = [undefined];//在变量有默认值的时候,只有当解构之后赋的值为undefined时,默认值才会生效,否则默认值会被解构之后的值覆盖。
    11        console.log(x);//4  
    12         
    13        let [x = {a:12}] = [null];//null是对象,不为空。
    14        console.log(x);//null

    当默认值为表达式时,表达式的求值是惰性的。

     1 function f(){
     2   console.log("aaa");
     3 }
     4 //let [x] = [1];
     5 //let [y] = [];
     6 let [z = f()] = [];
     7 let [z1 = f()] = [undefined];
     8         
     9 let [a = f()] = [1];
    10         
    11 //console.log(x);//1
    12 //console.log(y);//undefined
    13 console.log(z,z1);//aaa aaa undefined undefined  当然如果右侧换成[][undefined]的话,f()执行。
    14 console.log(a);//1 因为被解构的值是1,所以默认值不会生效,于是f()也就没有必要执行,它也确实没有执行,因为如果执行的话,会打印aaa。
    15 //当默认值为表达式时,表达式的求值时惰性的。

    默认值还可以引用解构赋值的其他变量,但前提是该变量必须已经声明,即被引用变量必须排在引用变量的前面。

    1         //let [x = 1, y = x] = [];//1 1
    2         //let [x = 1, y = x] = [2];//2 2 先确定x的值是2
    3         //let [x = 1, y = x] = [1,2];  //1 2    
    4         let [x = y,y = 1] = [];//ReferenceError引用错误 原因:x用到默认值y的时候,y还没有被声明。
    5 
    6         console.log(x,y);    

    对象的解析赋值

     赋值规则与数组的解构赋值本质上是一样的,都是解析等号两边的模式,然后将对应位置上的数据关联起来。但与数组不同的是,对象是通过键来区分内部成员的,而非数组里面的位置,所以对象的解构与变量的位置无关。

     1         // let {a,b} = {
     2         //     b: 2,
     3         //     a: 23
     4         // };
     5         // console.log(a,b);//23 2
     6 
     7             // let {a, b} = {a:23,b:2};//简写
     8             // let {a:a, b:b} = {a:23,b:2};//全写
     9             // console.log(a,b);
    10 
    11             let {a:c, b:d} = {a:23,b:2};
    12             console.log(c,d);13         console.log(c,d);//undefined 这里的a,b并非变量,是用来匹配的模式,所以没有定义。
    14 
    15         // let a = 1;
    16         // let obj = {a};
    17         // console.log(obj);//{a:1}
    18 
    19         // let a = 1;
    20         // let obj = {a: a};
    21         // console.log(obj);//{a:1}

    与数组一样,解构也可以用于嵌套解构的对象:

    1         let obj = {
    2             p:[
    3                 "hello",{y:"world"}
    4             ]
    5         };
    6 
    7         let {p:[x,{y}]} = obj;
    8         console.log(x,y);//hello world

    字符串的解析赋值

    字符串也可以解构赋值,这是因为此时,字符串被转换成了一个类似数组的对象。

    1         const [a,b,c,d] = "meng";
    2         console.log(a,b,c,d);//m e n g
    3 
    4         const {length} = "meng";
    5         console.log(length);//4

    同时,作为三个基本包装类型之一,字符串还可以调用String对象的一些方法:

    let {indexOf} = "meng";
    console.log(indexOf === String.prototype.indexOf);//true

    可以知道,解构赋值时,如果等号右面时数值、字符串和布尔值三种基本包装类型,则会优先转化为对象。

    参数的解析赋值

    参数的解构赋值本质数组的解构赋值或者对象的解构赋值。

          //函数传参解构:讲一个数组或者对象作为参数传进一个函数,真正能被函数感知的是参数解构之后被赋值的变量。
            function show({a,b}){
                console.log(a,b);
            }
            show({
                a:1,b:2
            });
    
            //函数传参解构2默认值
            function show2({a,b="默认"}){
                console.log(a,b);
            }
            show2({
                a:1
            });
    
            //函数传参解构全部默认
            function show3({a="hhdhd",b="默认"}){
                console.log(a,b);
            }
            show3({});
    
            //函数特性
            function show4({a="hhdhd",b="默认"}={}){
                console.log(a,b);
            }
            show4();

    在React无状态组件时:

        ComponentA = (props) => {
                return (
                    <div>props.name + props.age</div>
                );
            }
    
            //改进
            这里props是组件实例化时传入一个包含所有prop的对象,可以解构成:
            ComponentA = ({name,age}) => {
                return (
                    <div>name + age</div>
                );
            }
            

    默认值情况:

     1         //{x = 0,y = 0} = {}
     2         //参数X和Y在解构时的默认值是0,同时设置函数move的的默认参数是{},
     3         //当什么都没有传给函数move的时候,就等于把{}传给move,
     4         //此时,x和y有一个默认的解构时候0。当传入函数的值,解构后可以对x和y赋值时,则为x,y为新赋的值。
     5         function move({x = 0,y = 0} = {}){
     6             return [x,y];
     7         }
     8 
     9         let aaa = move({x:3,y:8});//[3,8]
    10         aaa = move();//[0,0]
    11         aaa = move({x:3});//[3,0]
    12         aaa = move({});//[0,0]
    13         console.log(aaa);

    另一个demo:

     1         //function move({x:0,y:0}) {x,y}= {x:0,y:0}的意思不是单独为x和y赋默认值只能函数的参数赋默认为{x:0,y:0},意即当什么都没有传入的时候,等于将{x:0,y:0}传给函数
           //所以当将{}作为参数传入的时候,{x,y}={}解析之后[undefined,undefined]
    2 function move({x,y} = {x:0,y:0}){ 3 return [x,y]; 4 } 5 6 let aaa = move({x:3,y:8});//[3,8] 7 aaa = move();//[0,0] 8 //aaa = move({x:3});//[3,undefined] 9 //aaa = move({});//[undefined,undefined] 10 console.log(aaa);

    总之,第一个例子是:对象解构赋值的默认值+函数参数的默认值;

    第二个例子,函数参数默认值。

  • 相关阅读:
    (原)Lazarus 异构平台下多层架构思路、DataSet转换核心代码
    (学)新版动态表单研发,阶段成果3
    (学) 如何将 Oracle 序列 重置 清零 How to reset an Oracle sequence
    (学)XtraReport WebService Print 报错
    (原)三星 i6410 刷机 短信 无法 保存 解决 办法
    (原) Devexpress 汉化包 制作工具、测试程序
    linux下网络配置
    apache自带ab.exe小工具使用小结
    Yii::app()用法小结
    PDO使用小结
  • 原文地址:https://www.cnblogs.com/liubeimeng/p/10689075.html
Copyright © 2020-2023  润新知