1.关于解构和默认值的关系

    1. function foo(){
    2.     console.log('foo');
    3. }
    4. let [x=foo()]=[1];

    上面的代码执行后我们可以发现foo函数没有马上执行,其实内部的判断逻辑如下:

    1. let x;
    2. if ([1][0] === undefined) {
    3.      x = f();
    4. } else {
    5.     x = [1][0];
    6. }

    也就是说只有右边是undefined才会执行foo(),否则不执行,直接赋值。

    2.一些不能被对象解构的情况

    不可枚举类型不能被解构成功:

    1. var obj=Object.create(null,{
    2.     x:{
    3.     value:'x',
    4.         enumerable:true,
    5.     },
    6.     y:{
    7.     value:'y',
    8.         enumerable:false
    9.     }
    10. });
    11. let {...a}=obj;
    12. /*
    13. 结果:
    14. {x: "x"}
    15. */

    class的对象只能解构它的this上的对象,不能解构方法。

    1. class foo{
    2.     constructor(){
    3.     this.name='abc';
    4.     }
    5.     hello(){
    6.     console.log('hello');
    7.     }
    8. }
    9. var f=new foo();
    10. let {...b}=f;
    11. /*
    12. 结果:
    13. {name: "abc"}
    14. */

    3.解构的时候关于小括号的问题

    一般正常正确写法:

    1. //对象
    2. /*方式1*/
    3. let {key1:a}={key1:'aa'}
    4. /*方式2*/
    5. let b;
    6. ({key2:b}={key2:'bb'})
    7. //数组
    8. let [a]=[1]

    对象的第二种方式要用小括号阔起来,因为{}开头会被当成代码块。

    解构的时候小括号不能随便使用,在解构的模式中遇到了小括号就会报错,只有在解构的非模式部分才能用小括号,现在我们来一起分析一些错误情况:

    1. /*包裹整个模式出错*/
    2. let ([a])=[1]
    3. let ({key1:a})={key1:'aa'}/*包裹在外侧*/
    4. let {(key1:a)}={key1:'aa'}/*包裹在内侧*/
    5. ([a])=[1]
    6. ({key1:a})={key1:'aa'}
    7. /*包裹部分模式出错*/
    8. let {(key1):a}={key1:'aa'}/*key1是负责匹配的模式,不能包裹*/
    9. /*let和包裹非模式部分一起用出错*/
    10. let [(a)]=[1];/*相当于let (a)=1;这样会报错*/
    11. function foo([(z)]){}/*相当于let (z)报错*/

    我们可以发现,let和解构在一起更容易出错,排除上面的几种会出错的情况,剩下的不会出错的情况就是,非let和非模式部分括号不会出错:

    1. [(a)]=[1];
    2. ({key1:(a)}={key1:'aa'})

    整个匹配结构如下:

    回到顶部
    我要评论

    所有评论

      相关文章