• 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);

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

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

  • 相关阅读:
    文本检测和识别 代码结构梳理
    UnicodeDecodeError: 'utf-8' codec can't decode byte
    GPU 显存释放
    DCM 图片查看
    hive SQL 字母大小写转换
    vim常用命令之多行注释和多行删除
    js 模拟call、apply、bind实现
    CommonJS、AMD、CMD和ES6模块化区别
    js setTimeout setInterval 第三个参数说明
    js instanceof 实现原理
  • 原文地址:https://www.cnblogs.com/liubeimeng/p/10689075.html
Copyright © 2020-2023  润新知