• ES6学习笔记之解构赋值


    1、数组的解构赋值

    在以前,我们若是要将数组的每个元素分别赋值给不同变量,较为麻烦。如:

    let arr = [1, 2, 3];
    let a = arr[0];
    let b = arr[1];
    let c = arr[2];

    ES6中的解构赋值,允许我们写成这个样子。

    let [a, b, c] = [1, 2, 3];
    console.log(a, b, c);

    上面这段代码表示,可以从数组里面提取值,按照对应的位置,一一给变量赋值。

    //左右两边结构得一致
    let [a, [[b], c]] = [1, [[2], 3]];  
    console.log(a, b, c);   //1 2 3
    
    let [ , , d] = [1, 2, 3];
    console.log(d);   //3
    
    let [f, ...g] = [1, 2, 3];  //第一个赋值给f,其他剩余的都装入到数组g中
    console.log(f, g);  //1 [2,3]
    
    let [x, y, ...z] = [1];
    console.log(x, y, z); //1 undefined []

    解构不成功的时候,变量的值就会是undefined。不完全解构的情况,即等号左边只匹配一部分等号右边的数组,还是可以解构成功的。如下例:

    //解构不成功
    let [a,b] = [];
    console.log(a, b);  //undefined undefined
    let [x, y] = [1];
    console.log(x, y);  //1 undefined
    //不完全解构
    let [c, d] = [1, 2, 3];
    console.log(c, d);  //1 2

    只要某种数据结构具备Iterator接口,都可以采用数组形式的解构赋值。至于什么是Iterator接口,我们下篇再看。

    let [a] = 1;    //TypeError: 1 is not iterable

    等号右边的值是不可遍历的的结构,也就是说不具备Iterator,那么将会报错。set结构和generator函数也可以采用数组形式的解构赋值。

     解构赋值允许指定默认值。注意,ES6内部使用 === 来判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。

    //默认值
    let [a=1, b=2] = ['x'];
    console.log(a,b);   //x 2
    
    let [x, y] = [1, undefined];
    console.log(x,y);  //1 undefined
    
    let [z=1] = [null];
    console.log(z); //null (null不严格等于undefined,所以默认值未生效)

    2.对象的解构赋值

    解构也可以应用于对象,但对象的解构与数组有一个重要的不同点,即,数组的元素是按照次序排列的,变量的取值由其位置决定;对象的属性是没有次序的,变量要与属性名相同,才能取到正确的值。如果解构失败,变量的值为undefined。

    let {a, b} = {b:2, a:1};    //顺序不影响,变量名和属性名一致就可以
    console.log(a,b);   //1 2
    let {x} = {a:1, b:2};   //没有对应的同名属性
    console.log(x); //undefined

    对象的解构赋值,可以将对象的方法赋值到某个变量上。

    let {log} = console;    //将console对象的log方法赋值给log变量
    log('123');

    对象的解构赋值的内部机制是,先找到同名的属性,再赋值给对应的变量。

    let {a:x, b:y} = {a:1, b:2};
    console.log(x, y);  //1 2

    在上例中,a 和 b 是匹配的模式,x ,y 才是变量,把1 和 2 赋值给 x, y 。

    let person = {
        name: 'lisi',
        age: 12,
        friend:{
            fname: "zhangsan",
            fage: 10
        }
    }
    let {name, friend, friend:{fname}} = person;    
    console.log(name);  //lisi
    console.log(friend);    //{ fname: 'zhangsan', fage: 10 }
    console.log(fname); //zhangsan

    如上面代码,嵌套的对象也可以解构。上面代码有三次解构赋值,分别对属性name, friend, fname 进行解构赋值。最后对fname的解构赋值,friend只是模式,变量是fname.

    有时,我们会遇到这样的情况,如:animal:{person:{name}},animal 和person 都是模式,变量是 name。只要记住,最后一个冒号后面的就是变量,其他都是模式。

    注意,对象的解构赋值可以取到继承的属性。

    const obj1 = {};
    const obj2 = {a : 123};
    Object.setPrototypeOf(obj1, obj2);  //将obj2设置为obj1的原型对象
    
    const {a} = obj1;
    console.log(a); //123

    上面代码中,obj1 自身没有 a 属性,而是继承自obj2 的属性。解构赋值可以取到这个属性。

    对象的解构也可以指定默认值,与数组类似。

    数组本质上是特殊的对象,因此可以对数组进行对象属性的解构。

    let arr= [1, 2, 3];
    let {0 : a, [arr.length - 1] : b} = arr;
    console.log(a, b);  //1 3

    数组arr的第0个位置对应的是1,第[arr.length - 1]位置,也就是第2个位置对应的是3。

    3.字符串、数值、布尔值的解构赋值

    //字符串的解构赋值
    const [a, b, ...c] = 'hello';   //字符串被转换成了一个类似数组的对象
    console.log(a); //h
    console.log(b); //e
    console.log(c); //[ 'l', 'l', 'o' ]
    const {length : len} = 'hello'; //字符串被转换成类似于数组的对象,有length属性
    console.log(len);   //5
    
    //数值和布尔值的解构赋值
    //undefined和null无法转为对象,所以对它们进行解构赋值,会报错
    //等号右边是数值和布尔值时,会先转为对象,对象里面都有toString属性
    let {toString: a} = 123;    
    console.log(a); //[Function: toString]
    let {toString: b} = true;
    console.log(a); //[Function: toString]

    4.解构赋值的用途

    1. 交换变量的值
      let x = 1;
      let y = 2;
      [x, y] = [y, x];
    2. 从函数返回多个值
      //返回一个数组
      function show(){
          return [1,2,3];
      }
      let [a, b, c] = show();
      //返回一个对象
      function show(){
          return {
              name: 'lisi',
              age: 12
          };
      }
      let {a, b} = show();
    3. 函数参数的定义
      //参数是一组有次序的值
      function f1([x, y, z]) {
          console.log(x, y, z);
      }
      f1([1,2,3]);    //1 2 3
      //参数是一组无次序的值
      function f2({x, y, z}){
          console.log(x, y, z);
      }
      f2({z:3, y:2, x:1});    //1 2 3
    4. 提取JSON数据
      let json = {a:1, b:"hello", c:[1, 2, 3]};
      let {a, b, c} = json;
      console.log(a, b, c);   //1 'hello' [ 1, 2, 3 ]
    5. 函数参数的默认值
      function show({x=0, y=0}){
          console.log(x, y);
      }
      show({x: 1, y: 2}); //1 2
      show({x: 1});   //1 0
      show({});   //0 0
    6. 遍历Map结构
      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
    7. 输入模块的指定方法

     

  • 相关阅读:
    帮朋友写的两篇文章
    与疯姐的对话
    实现C(i,j)=A(m,n,w)+B(m,n)
    误差处理相关
    http://blog.sina.com.cn/s/blog_4aae007d0100inxi.html
    全局变量和局部变量
    Yeelink:将复杂的传感器以极简的方式组到同一个网络内
    基站分布:GDOP
    C++学习路线图
    Matlab中三点确定质心
  • 原文地址:https://www.cnblogs.com/ly2019/p/10970050.html
Copyright © 2020-2023  润新知