鲜荣彬
Herry

1、解构的含义  

    允许按照一定的模式,从数组和对象中取值,对变量进行赋值,称为解构。

    解构赋值时,只要等号右边的值不是对象,就先将其转换成对象。

 本质上,这种写法属于 “模式匹配”,只要两边模式相同,左边的变量就会被赋予对应的值。
let [head,...tail]=[1, 2, 3, 4]; //不完全解构,左边的模式,只匹配一部分的等号右边的数组

    解构后: head=1,tail=[2,3,4]。

 

2、解构的限制。

     (1)undefined与null 无法转换成对象,解构赋值就会报错

let { y } = null;    // Cannot match against 'undefined' or 'null'.

     (2)如果等号的右边不是数组,转换对象以后不具备 Iterator接口,或本身就不具备Iterator接口,

  即某种数据结构具有Iterator接口,都可以采用数组形式的解构赋值。
    let [foo]=1; //undefined is not a function,报错的行数会指向上一行代码

    let [foo1,foo2]=new Set(['a', 'b', 'c']);

 3、解构赋值时, 左边参数允许默认值。

    (1)ES6内部使用严格相对运算符,因此,若defaultValue!==undefined,默认值失效。
    var [x=1]=[undefined]; //x=1
    var [y=2]=[null];  //y=2

(2)赋予默认值时,左边参数 可以引用解构赋值的其他变量,但该变量必须已经声明.
let [x1=y1,y1=1]=[]; //error,因为此时y1还没有值,应该如此写: let[y=1,x=y]=[];

4、对象解构赋值

 对象属性没有次序,变量名必须与属性相同。
    let { fishInstance,dogInstance}={
        dogInstance: {
            name: 'dog',
            moveType: 'run'
        },
        fishInstance{
            name:'fish'
        }
    }

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

    真正被赋值的是后者,而不是前者。

let { oldName:newName}={oldName: '12222222', bar: 'barTest'}

6、

 let tree = {
        root: {
            leaf: {
                left: 5,
                right: 5
            }
        }
    }
var { root:{leaf:{left}} }=tree; //此时, root 与 leaf 都是模式,不会被赋值,只有leaf是变量
console.log(root);  /*root is not defined*/


7、对象的解构也可以指定默认值,生效的条件是对象的属性严格等于 undefined

 如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,则error。
 let {x=3}={};

 let { foo: { name }}={bar: 'bar'};

 将一个已经申明的变量用于解构赋值,必须非常小心。
 let temp;
 {temp}= {x: 1}; /error

 ( { temp }={x: 1} ); //使用圆括号,避免JS引擎将 "{ }" 解释为代码块

8、字符串解构赋值,会将字符串转换成类似数组的对象。
 const [a,b,c,d,e]='hello world';
    let { length:strLen }='world';

 9、解构 数值和布尔值时,先转换成对象

   let { toString:s1 } =123; //s1===Number.prototype.toString

    let { toString: s2}=true; //s2===Boolean.prototype.toString

解构使用场景
  (1)可以很方便的将 现有对象的方法,赋值给某个变量.
let { log: selfLog}=console;
selfLog('test log');
  (2)交换变量.
[x,y]=[y,x];
  (3)从函数返回多个值
    function getPerson() {
        return {
            name: 'jack',
            age: 19
        }
    }

    var {name,age}=getPerson();
  (4) 定义函数参数后,可以不按顺序传入
    function setPerson({name,age,address}) {

    }

    setPerson({age: 19, address: 'china', name: 'Tom'});
  (5)提取JSON对象中的数据
  let jsonData = {
        age: 19,
        name: 'Tom',
        son: [
            'little Jack',
            'little Tom'
        ]
    };

    let { son:child }=jsonData;
  (6)遍历map结构
    var map =new Map();

    for(let [key,value] of map) { }

    for(let [,value] of map ) { }
  (7)获取模块的指定方法

 const { SourceMapConsumer }= require('');

 



posted on 2017-05-03 17:27  Herry彬  阅读(2776)  评论(0编辑  收藏  举报