9、ES6 对象的解构赋值

1、解构不仅可以用于数组,还可以用于对象

                   对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

2、指定默认值

               默认值生效的条件是,对象的属性值严格等于undefined。

3、现有对象的方法

              对象的解构赋值,可以很方便的将现有对象的方法,赋值到某个变量。



解构不仅可以用于数组,还可以用于对象。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo</title>
    <script src="js/traceur.js"></script>
    <script src="js/bootstrap.js"></script>
    <script type="text/traceur">
        var {foo,bar}={foo:"aaa",bar:"bbb"};
        console.log(foo); //aaa
        console.log(bar);  //bbb
    </script>
</head>
<body>
     
</body>
</html>

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

 var {bar,foo}={foo:"aaa",bar:"bbb"};
        console.log(foo); //aaa
        console.log(bar);  //bbb


      var {baz}={foo:"aaa",bar:"bbb"};
        console.log(baz);  //undefined

上面代码的第一个例子,等号左边的两个变量的次序,与等号右边两个同名属性的次序不一致,但是对取值完全没有影响。第二个例子的变量没有对应的同名属性,导致取不到值,最后等于†‡ˆ‹‡† undefined 。

如果变量名与属性名不一致,必须写成下面这样。

var {foo:baz}={foo:"aaa",bar:"bbb"};
       console.log(baz); //aaa
        
        let obj={first:'hello',last:'world'};
        let {first:f,last:l}=obj;
        console.log(f);  //hello
        console.log(l);  //world

这实际上说明,对象的解构赋值是下面形式的简写:

var {foo:foo,bar:bar}={foo:"aaa",bar:"bbb"};

也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

var {foo:baz}={foo:"aaa",bar:"bbb"};
       console.log(baz);  //aaa
       console.log(foo);  //foo is not defined

上面代码中,真正被赋值的是变量„ƒœ baz,而不是模式ˆ‘‘ foo。

注意,采用这种写法时,变量的声明和赋值是一体的。对于let和const来说,变量不能重新声明,所以一旦赋值的变量以前声明过,就会报错。

       let foo;
       let {foo}={foo:1};
       console.log(foo);  //报错


       let baz;

       let {bar:baz}={bar:1};  //报错

上面代码中,解构赋值的变量都会重新声明,所以报错了。不过,因为ƒ var 命令允许重新声明,所以这个错误只会在使用Ž‡ let 和…‘• const 命令时出现。如果没有第二个let命令,上面的代码就不会报错。Ž‡

let foo;
       ({foo}={foo:1});
       console.log(foo); //1  

       let baz;
       ({bar:baz}={bar:1});
       console.log(baz);  //1

       和数组一样,解构也可以用于嵌套结构的对象。

   var obj={
             p:[
            "hello",
            {y:"world"}
             ]
       };

       var {p:[x,{y}]}=obj;
       console.log(x);  //hello
       console.log(y);  //world

注意,这时’ p 是模式,不是变量,因此不会被赋值。

 var node={
          loc:{
          start:{
              line:1,
              column:5
          }
          }
      };

      var {loc:{start:{line}}}=node;
      console.log(line);  //1
      console.log(loc);   //loc is not defined
      console.log(start);  //start is not defined

上面代码中,只有Ž‹‡ line 是变量,Ž‘… loc 和•ƒ start 都是模式,不会被赋值。

下面是嵌套赋值的例子。

      let obj={};
       let arr=[];

       ({foo:obj.prop,bar:arr[0]}={foo:123,bar:true});
       console.log(obj); //{prop: 123}
       console.log(arr); //[true]

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

       var {x=3}={};
       console.log(x); //3

      var {x,y=5}={x:1};
      console.log(x);  //1
      console.log(y);  //5

     var {message:msg="something well"}={};
      console.log(msg);  //something well

默认值生效的条件是,对象的属性值严格等于†‡ˆ‹‡† undefined。

     var {x=3}={x:undefined};
      console.log(x);  //3

     var {x=3}={x:null};
      console.log(x);  //null


上面代码中,如果š x属性等于nullŽŽ ,就不严格相等于undefined†‡ˆ‹‡† ,导致默认值不会生效。

如果解构失败,变量的值等于†‡ˆ‹‡† undefined†‡ˆ‹‡†。

     var {foo}={bar:'baz'};
      console.log(foo);  //undefined

如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。

      var {foo:{bar}}={baz:'baz'};
      console.log(foo);  //Cannot read property 'bar' of undefined  (报错)

上面代码中,等号左边对象的 ˆ‘‘foo  属性,对应一个子对象。该子对象的„ƒ bar 属性,解构时会报错。原因很简单,因为ˆ‘‘ foo 这时等于†‡ˆ‹‡† undefined ,再取子属性就会报错,请看下面的代码。ƒ

       var _tmp={baz:'baz'};
     console.log(_tmp.foo.bar);  //报错


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

//错误写法
      var x;
      {x}={x:1};
      console.log(x);

上面代码的写法会报错,因为JavaScript引擎会将 {x} 理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免JavaScript将其解释为代码块,才能解决这个问题。

//正确的写法
     ({x}={x:2});

上面代码将整个解构赋值语句,放在一个圆括号里面,就可以正确执行。关于圆括号与解构赋值的关系,参见下文。

解构赋值允许,等号左边的模式之中,不放置任何变量名。因此,可以写出非常古怪的赋值表达式。

     ({}=[true,false]);
     ({}='abc');
     ({}=[]);

上面的表达式虽然毫无意义,但是语法是合法的,可以执行。

对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。

 let {log,sin,cos}=Math;

上面代码将ƒŠ Math 对象的对数、正弦、余弦三个方法,赋值到对应的变量上,使用起来就会方便很多。





-----------------------------------------------------------对象的解构赋值不用按顺序----------------------------------------------------

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>对象的解构赋值不用按顺序</title>
    <script src="js/traceur.js"></script>
    <script src="js/bootstrap.js"></script>
    <script type="text/traceur">
       var {name,age,id}={id:"007",name:"lyf",age:22};
       console.log(name); //lyf
       console.log(age);  //22
       console.log(id);  //007
    </script>
</head>
<body>
    
</body>
</html>


------------------------------------------------------变量名与属性名不一致的情况----------------------

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>变量名与属性名不一致</title>
    <script src="js/traceur.js"></script>
    <script src="js/bootstrap.js"></script>
    <script type="text/traceur">
       var {personname,personage,personid}={id:"007",name:"lyf",age:22};
       console.log(personname); //undefined
       console.log(personage);  //undefined
       console.log(personid);  //undefined

       var {name:personname,age:personage,id:personid}={id:"007",name:"lyf",age:22};
       console.log(personname); //lyf
       console.log(personage);  //22
       console.log(personid);  //007

       let object={first:"Hello",last:"World"};
       let {first:firstName,last:lastName}=object;
       console.log(firstName); //Hello
       console.log(lastName);  //World
    </script>
</head>
<body>
    
</body>
</html>


-------------------------------------------------------对象解构默认值-----------------

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>对象解构默认值</title>
    <script src="js/traceur.js"></script>
    <script src="js/bootstrap.js"></script>
    <script type="text/traceur">
       var {x="lyf"}={};
       console.log(x); //lyf

       var {x,y=5}={x:1};
       console.log(x); //1
       console.log(y); //5

       var {message:msg="you are creaze"}={};
       console.log(msg); //you are creaze
    </script>
</head>
<body>
    
</body>
</html>


-----------------------------------------------

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>对象解构默认值条件</title>
    <script src="js/traceur.js"></script>
    <script src="js/bootstrap.js"></script>
    <script type="text/traceur">
         var {x=3}={x:undefined};
         console.log(x); //3

         var {y=3}={y:null};
         console.log(y); //null   (原因是:默认值生效的条件是,对象的属性值严格等于undefined。)
    </script>
</head>
<body>
    
</body>
</html>


----------------------------已声明变量的解构赋值------------------------

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>已声明变量的解构赋值</title>
    <script src="js/traceur.js"></script>
    <script src="js/bootstrap.js"></script>
    <script type="text/traceur">
         var x;
         ({x}={x:1});   //不加()会报错
         console.log(x); //1

    </script>
</head>
<body>
    
</body>
</html>

------------------------------------现有对象的方法----------------------

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>现有对象的方法</title>
    <script src="js/traceur.js"></script>
    <script src="js/bootstrap.js"></script>
    <script type="text/traceur">
        console.log(Math.sin(Math.PI/6)); //0.49999999999999994
        
        let {sin,cos,tan}=Math;
        console.log(sin(Math.PI/6));//0.49999999999999994
    </script>
</head>
<body>
    
</body>
</html>








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值