码迷,mamicode.com
首页 > 其他好文 > 详细

解构赋值

时间:2018-05-09 19:29:40      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:bool   null   code   bsp   嵌套   必须   else   没有   moved   

          <script type="text/javascript">
        /*传统赋值*/
            function tradition(){
                let a=1;
                let b=2;
                let c=3;
            };
            tradition();
            
            /*ES6赋值*/
            function ES6(){
                //1.数组的解构赋值
                this.assignment=function(){
                    let [a,b,c] = [1,2,3];
                    console.log([a,b,c]);//1,2,3
                    
                    let [foo,[[bar],jpg]] = [1,[[2],3]];
                    console.log([foo,[[bar],jpg]]);//[1,[2,[3]]]
                    
                    let [,,third] = ["foo",‘bar‘,‘123‘];
                    console.log([,,third]);//exmpt,exmpt,123
                    
                    let [x, , y] = [1, 2, 3,[1,2,3]];
                    console.log([x, , y]);//1,exmpt,3
                    
                    let [head,...tail] = [1,2,3,4,5];
                    console.log(head,tail);//1,[2,3,4,5]
                    
                    let [yy,ll,...qq] = [‘a‘];
                    console.log(yy,ll,qq)//a undefined []
                    /*总结:左右对等:结果一样,变量多多值少:打印出被赋值的变量,没有赋值成功的变量则为undefined。变量少值多:打印出赋值的变量,属于不完全结构,但可以成功赋值*/
                };
                //如果右边不是数组。严格来说,不是可遍历的结构,那么将会报错,
                this.errorArray=function(){
                    let[foo]=1;
                    let[foo]=false;
                    let[foo]=NaN;
                    let[foo]=undefined;
                    let[foo]=null;
                    let[foo]={};
                    /*上面语句都会报错,因为上面前五个的值转为对象以后不具备Iterator接口,最后一个本身就不具备Iterator接口*/
                };
                //对于Set结构,我们还可以用数组的解构赋值。
                this.set=function(){
                    let[x,y,z,g] = new Set([‘a‘,‘b‘,‘c‘]);
                    console.log(x,y,z,g)//a,b,c undefined
                };
                //只有某种数据结构具有Iterator接口,都可以采用数组形式的结构赋值。
                this.Iterator=function(){
                    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();
                    console.log(sixth);//5
                };
                //默认值:解构赋值允许默认值,还可以引用结构赋值的其他变量,但该变量必须已经声明。
                this.defaultValue=function(){
                    let[foo = true] = [];
                    console.log(foo);//true
                    
                    let[x,y="b"] =[1];
                    console.log(x,y);//1,b
                    
                    let [xx, yy = ‘b‘] = [‘a‘, undefined]; // x=‘a‘, y=‘b‘
                    console.log(xx,yy);//1,b
                    
                    let [num = 1] = [undefined];
                    console.log(num);

                    let [Number = 1] = [null];
                    console.log(Number);
                    
                    let [bgg=num,xm=Number] = [undefined];
                    console.log(bgg,xm);
                    
                    let [h=num,t=h] = [1,5];
                    console.log(h,t);
                    /*总结:es6内部使用严格相等运算符(===),判断一个位置是否具有值,所以,只有当一个数组成员严格等于undefined,默认值才会生效*/
                    
                    
                };
                //表达式:惰性执行
                this.expression=function(){
                    function f(){
                        console.log("aaa");
                    };
                    let [ff = f()]=[1];
                    //上面的代码等价于下面的代码。同样也是只要右边有赋值,就不会执行默认值的函数。
                    let func;
                    if([1][0]===undefined){
                        func=f();
                    }else{
                        func=[1][0];
                    };
                    console.log(func)
                };
                //2.对象的解构赋值,
                /*对象的解构与数组有一个重要的不同,数组的元素是按照次序排列的,变量的取值由它的位置界决定,而对象的属性没有次序,变量必须与属性同名,才能渠道正确的值。*/
                this.obj =function(){
                    console.log("this.obj:对象的解构赋值");
                    let{foo,bar} = {foo:[{id:"1",name:"你好"},{id:"2",name:"你好000"}],bar:"bbb"};
                    console.log(foo,bar);
                    
                    //变量没有对应的同名属性,导致取不到值,最后等于undefined。
                    let {bzz}={foo:"aaa",bar:"bbb"};
                    console.log(bzz)//undefined;
                    
                    //1.次序颠倒
                    let{foot,baz} = {baz:"baz",foot:"foot"};
                    console.log(foot,baz)//foot,baz
                    
                    //如果变量名与属性名不一致,必须写成下面这样。
                    let {footer:header,hed:head} = {footer:‘aaa‘,hed:"bbb"};
                    console.log(header,head)//aaa,bbb
                    //这实际上说明,对象的解构赋值是上面形式的简写。
                    
                    let obj = {first:"hello",last:‘world‘};
                    let {first:f,last:l} =obj;
                    console.log(f,l)//heoll,world;
                    
                    let { num: num2 } = { num: "aaa", num2: "bbb" };
                    //num2  "aaa"
                    //num  error: foo is not defined
                    //上面代码中,num是匹配的模式,num2才是变量。真正被赋值的是变量num2,而不是模式num。
                    
                    
                    //2.和数组一样,解构也可以用于嵌套结构的对象
                    let obje = {
                        p:[
                            "hello",
                            {y:"world"}
                        ],
                    };
                    let{p:[x,{y}]} =obje;
                    console.log(x,y)//heoll,world
                    
                    let{p:bgg} =obje;
                    console.log(bgg)//obje对象
                    //p并不是变量。如果想要p成为变量
                    
                    let{p,p:[xx,{yy}]} = obje;
                    console.log(p)//obje对象
                    
                    const noded = {
                          loc: {
                            start: {
                              line: 1,
                              column: 5
                            }
                          }
                    };
                    let { loc, loc: { start }, loc: { start: { line }} } = noded;
                    console.log(loc);//start: {line: 1,column: 5};
                    console.log(start);//{line: 1,column: 5};
                    console.log(line);//1;
                    /*注意,最后一次对line属性的解构赋值之中,只有line是变量,loc和start都是模式,不是变量。*/
                
                    
                    
                };
                /*下面是嵌套赋值的例子*/
                this.nest =function(){
                    console.log("this.nest:下面是嵌套赋值的例子");
                    let Object ={};
                    let arr = {};
                    ({boo:Object.prop,zar:arr[0]}={boo:123,zar:true});
                    console.log(Object,arr);
                };
                /*对象的解构也可以指定默认值*/
                this.objMore=function(){
                    console.log("this.objMore:对象的解构也可以指定默认值")
                    var {x = 3}={};
                    console.log(x)//3
                    var {x,y=5}={x:1};
                    console.log(x,y)//1,5
                    var {x:y=3}={x:5};
                    console.log(y)//5
                    /*默认值生效的条件是,对象的属性值严格等于undefined。*/
                    var {b=3} = {b:undefined};
                    console.log(b)//3
                    var {b=3} = {b:null};
                    console.log(b)//null
                    //如果解构失败,变量的值等于undefined。
                    let{bgg} = {bar:"bza"};
                    console.log(bgg)//undefined
                    //如果子对象的父属性没有被定义,则会报错
                    //var {foo: {bart}} = {baz: ‘baz‘,};
                    //console.log({bart});

                    //下面的定义了就不会报错。
                    let {foo: {bart}} = {foo:{bart:{id:1}},baz: ‘baz‘,};
                    console.log({bart})
                }
                //对象语法圆括号和花括号问题
                this.garmmar=function(){
                    //如果将一个已经声明的变量进行解构赋值,要非常小心
                    let x;
                    //{x}={x:1};
                    //报错原因:js引擎会将{x}解析成代码块,而并不是一个对象,只有将花括号不写在首行就行。
                    ({x}={x:1});
                    console.log(x);//1
                    
                    /*解构赋值允许等号左边的模式中不放置任何变量,这个是合法的,但是毫无意义*/
                    ({}={x:1});
                    ({}=[true,false]);
                    ({}=[]);
                    ({}="abc");
                    
                    //对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。
                    
                    let { log, sin, cos } = Math;
                    console.log(log);
                    
                    //由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
                    let array =[1,2,3];
                    let {0:first,[array.length-1]:last}=array;
                    console.log(first,last);//1,3
                };
                /*字符串的解构赋值*/
                this.stringF=function(){
                    /*字符串也可以解构赋值。字符串被转换成了一个类似数组的对象。*/
                    const [a,b,c,d,e] = "hello";
                    console.log(a,b,c,d,e)//h e l l o
                    /*既然可以转化为数组,那么必然会有length*/
                    const{length:len} ="hello";
                    console.log(len);
                };
                /*4.数值和布尔值的解构赋值*/
                /*解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。*/
                this.booleanAndnumber=function(){
                    var {toString:s} =123;
                    console.log(s === Number.prototype.toString);
                    var {toString:s} =true;
                    console.log(s === Boolean.prototype.toString);
                    
                    /*解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。*/

                    //var { prop: x } = undefined; // TypeError
                    //var { prop: y } = null; // TypeError
                };
                //5.函数参数的解构赋值
                this.func=function(){
                    function add([x,y]){
                        return x+y;
                    };
                    console.log(add([1,2]));//3
                    
                    
                    [[1,2],[3,4]].map(function([a,b]){
                        console.log([a,b])//[1,2],[3,4]
                        return a+b,console.log(a+b);//3,7
                    });
                    
                    /*函数参数的解构也可以用默认值*/
                    
                    function move({x=12,y=12}={}){
                        return [x,y];
                    };
                    move();//24
                    move({x:24,y:24});//48
                    move({});
                    
                    //注意,下面的写法会得到不一样的结果。
                    function moved({x, y} = { x: 0, y: 0 }) {
                      return [x, y];
                    }
                    
                    moved({x: 3, y: 8}); // [3, 8]
                    moved({x: 3}); // [3, undefined]
                    moved({}); // [undefined, undefined]
                    moved(); // [0, 0];
                    //undefined就会触发函数参数的默认值。
                    [1,undefined,3].map(function(x="yes"){
                        console.log(x)//1,yes,3
                    });
                    
                };
                //圆括号的问题
                this.roundBrackets=function(){
                    //不能使用圆括号的3中方式
                    /*1.变量声明语句*/
                    //let [(a)] = [1];报错,缺少括号
//                    var {x:(c)}={}//虽然内部是正确的,但是被声明了。
//                    var {(x):c}={}//内部都是错的,不能使用在模式上面。
//                    var ({x: c}) = {};//内部错了,并且声明了语句。圆括号不能包裹模式。
//                    var {(x: c)} = {};//同上。
                    
//                    /*2.函数参数*/
//                    /*函数参数也属于变量声明,因此不能带有圆括号。*/
//                    function f([(z)]){return z;};
//                    function ff(([z,(x)]))(return x;);
//                    
//                    //3.赋值语句的模式
//                    ({p:a})={p:42};
//                    ([a]) = [5];
//                    [({p:a}),{x:c}]=[{},{}];
//                    都是缺少括号,都报错

                    /*可以使用圆括号的情况只有一种:赋值语句的非模式部分。*/
                    [(b)] = [3]; // 正确
                    console.log((b));//3
                    ({p:(a)}= {p:12});
                    console.log(a);
                    [(parseInt.prop)]=[3];
                    console.log(parseInt.prop);
                };
                /*用途*/
                this.user=function(){
                    /*1.交换变量的值*/
                    let x=1;
                    let y=2;
                    [x,y]= [y.x];//2,1
                    
                    /*2.从函数返回多个值*/
                    /*返回一个数组*/
                    function arr (){
                        return[1,2,3];
                    };
                    let [a,b,c] = arr();
                    console.log(a,b,c)//1,2,3
                    
                    /*返回一个对象*/
                    function obj(){
                        return{
                            foo:1,
                            bar:2
                        };
                    };
                    let{foo,bar}=obj();
                    console.log(foo,bar);//1,2
                    
                    //(3)函数参数的定义
                    //解构赋值可以方便地将一组参数与变量名对应起来。    
                    // 参数是一组有次序的值
                    function wellf([x, y, z]) { /*...*/ };
                    wellf([1, 2, 3]);
                    
                    // 参数是一组无次序的值
                    function unordered({x, y, z}) { /*...*/ };
                    unordered({z: 3, y: 2, x: 1});
                    
                    
                    //(4)提取 JSON 数据
                    //解构赋值对提取 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]
                    
                    //(5)遍历 Map 结构
                    //任何部署了 Iterator 接口的对象,都可以用for...of循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便。
                    const map = new Map();
                    
                    map.set(‘first‘, ‘hello‘);
                    map.set(‘second‘, ‘world‘);
                    for (let [key, value] of map) {
                      console.log(key + " is " + value);
                    };
                    // first is hello
                    // second is world
                    
                    //如果只想获取键名,或者只想获取键值,可以写成下面这样。
                    // 获取键名
                    for (let [key] of map) {
                      // ...
                    };
                    // 获取键值
                    for (let [,value] of map) {
                      // ...
                    };
                    
                    //(6)输入模块的指定方法

                    //加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。
                    
                    const { SourceMapConsumer, SourceNode } = require("source-map");
                };
            };
            var modern = new ES6();
            modern.assignment();
            modern.set();
            modern.Iterator();
            modern.defaultValue();
            modern.expression();
            modern.obj();
            modern.nest();
            modern.objMore();
            modern.garmmar();
            modern.stringF();
            modern.booleanAndnumber();
            modern.func();
            modern.roundBrackets();
            modern.user(); 
        </script>            

 

解构赋值

标签:bool   null   code   bsp   嵌套   必须   else   没有   moved   

原文地址:https://www.cnblogs.com/MJ-MY/p/9015730.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!