zoukankan      html  css  js  c++  java
  • ECMAScript6

    1.数组解构赋值

    1.1.基本用法

        // (1)对数组变量赋值
          let [foo, [[bar], baz]] = [1, [[2], 3]];
          foo; // 1
          bar; // 2
          baz; // 3
    
          let [, , third1] = ["foo", "bar", "baz"];
          third1; // "baz"
    
          let [aa, , bb] = [1, 2, 3];
          aa; // 1
          bb; // 3
    
          let [head, ...tail] = [1, 2, 3, 4];
          head; // 1
          tail; // [2, 3, 4]
    
          //(2)解构不成功(变量数 > 赋值数) 1.
          let [x, y, ...z] = ["a"];
          x; // "a"
          y; // undefined
          z; // []
    
          //解构不成功 2.
          let [foo1] = [];
          let [bar1, foo2] = [1];
          foo1; // undefined
          bar1; // 1
          foo2; // undefined
    
          //(3)解构不完全(变量数 < 赋值数) 1.
          let [x1, y1] = [1, 2, 3];
          x1; // 1
          y1; // 2
    
          //解构不完全 2.
          let [a, [b], d] = [1, [2, 3], 4];
          a; // 1
          b; // 2
          d; // 4
    
          //(4)如果等号的右边不是数组-->报错
          //   let [foo] = 1;
          //   let [foo] = false;
          //   let [foo] = NaN;
          //   let [foo] = undefined;
          //   let [foo] = null;
          //   let [foo] = {};
    
          //(5) Set 结构,也可以使用数组的解构赋值
          let [e, f, g] = new Set(["a", "b", "c"]);
          e; // "a"
          f; // "b"
          g; // "c"
    
          // (6) 只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。
          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();
          sixth; // 5
    

    1.2.默认值

     {
            let [foo = true] = [];
            foo; // true
    
            let [x, y = "b"] = ["a"]; // x='a', y='b'
            let [a, b = "b"] = ["a", undefined]; // a='a', b='b'
          }
    
          // (2)ES6 内部使用严格相等运算符(===),判断一个位置是否有值。只有当一个数组成员严格等于undefined,默认值才会生效。
          {
            let [x = 1] = [undefined];
            x; // 1
    
            let [y = 1] = [null];
            y; // null    如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。
          }
    
          // (3)默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。
          function f() {
            console.log("aaa");
          }
    
          let [x = f()] = [1];
          x;
    
          //等价于上面  let [x = f()] = [1];
          let y;
          if ([1][0] === undefined) {
            y = f();
          } else {
            y = [1][0];
          }
    
          // (4)默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
          let [c = 1, d = c] = []; // c=1; d=1
          let [e = 1, g = e] = [2]; // e=2; g=2
          let [h = 1, i = h] = [1, 2]; // h=1; i=2
          let [j = k, k = 1] = []; // ReferenceError: k is not defined  -> k没有声明
    

    对象

    //(1) 基础用法
          {
            let { foo, bar } = { foo: "aaa", bar: "bbb" }; //等价于 let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
            foo; // "aaa"
            bar; // "bbb"
          }
    
          //(2) 变量名与属性名不一致:错误写法
          {
            let { bar, foo } = { foo: "aaa", bar: "bbb" };
            foo; // "aaa"
            bar; // "bbb"
    
            let { baz } = { foo: "aaa", bar: "bbb" };
            baz; // undefined
          }
    
          //(3) 变量名与属性名不一致:正确写法
          {
            let { foo: baz } = { foo: "aaa", bar: "bbb" };
            baz; // "aaa"
            // foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo。
    
            let obj = { first: "hello", last: "world" };
            let { first: f, last: l } = obj;
            f; // 'hello'
            l; // 'world'
          }
    
          //(4) 嵌套结构:数组一样,解构也可以用于嵌套结构的对象。 这时p是模式,不是变量,因此不会被赋值
          {
            let obj = {
              p: ["Hello", { y: "World" }]
            };
    
            let {
              p: [x, { y }]
            } = obj;
            x; // "Hello"
            y; // "World"
          }
    
          //(5) 嵌套结构:如果p也要作为变量赋值,可以写成下面这样。
          {
            let obj = {
              p: ["Hello", { y: "World" }]
            };
    
            let {
              p,
              p: [x, { y }]
            } = obj;
            x; // "Hello"
            y; // "World"
            p; // ["Hello", {y: "World"}]
          }
    
          //(6) 只有line是变量,loc和start都是模式
          {
            const node = {
              loc: {
                start: {
                  line: 1,
                  column: 5
                }
              }
            };
    
            let {
              loc,
              loc: { start },
              loc: {
                start: { line }
              }
            } = node;
            line; // 1
            loc; // Object {start: Object}
            start; // Object {line: 1, column: 5}
          }
    
          //(7) 嵌套赋值:
          {
            let obj = {};
            let arr = [];
    
            ({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
    
            obj; // {prop:123}
            arr; // [true]
          }
          //(8) 默认值
          {
            var { x = 3 } = {};
            x; // 3
    
            var { a, b = 5 } = { a: 1 };
            a; // 1
            b; // 5
    
            var { c: d = 3 } = {};
            d; // 3
    
            var { e: f = 3 } = { e: 5 };
            f; // 5
    
            var { message: msg = "Something went wrong" } = {};
            msg; // "Something went wrong"
          }
    
          //(9) 默认值生效的条件是,对象的属性值严格等于undefined。
          {
            var { x = 3 } = { x: 4 };
            x; // 3
    
            var { y = 3 } = { y: null };
            y; // null
          }
    
          //(10) 解构失败
          {
            let { foo } = { bar: "baz" };
            foo; // undefined
          }
    
          //(11) 嵌套的对象,而且子对象所在的父属性不存在
          {
            //// 报错,等号左边对象的foo属性,对应一个子对象。该子对象的bar属性,解构时会报错。原因很简单,因为foo这时等于undefined,再取子属性就会报错,
            // let {
            //   foo: { bar }
            // } = { baz: "baz" };
            //// 对上面的解读
            // let _tmp = { baz: "baz" };
            // _tmp.foo.bar; // 报错 _tmp.foo = undefined 再取子属性就会报错
          }
    
          //(12) 已经声明的变量用于解构赋值
          {
            let x;
            // 错误的写法
            // {x} = {x: 1};   这里{x} 被理解为代码块
    
            // 正确的写法
            ({ x } = { x: 1 });
            console.log(x);
            // SyntaxError: syntax error
          }
    
          //(13) 解构赋值允许等号左边的模式之中,不放置任何变量名 -> 虽然毫无意义,但是语法是合法的,可以执行。
          {
            ({} = [true, false]);
            ({} = "abc");
            ({} = []);
          }
    
          //(14) 代码将Math对象的对数、正弦、余弦三个方法,赋值到对应的变量上,使用起来就会方便很多。
          let { log, sin, cos, PI } = Math;
          console.log(sin); //sin() { [native code] }
          console.log(PI); //3.141592653589793
    
          //(15) 由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
          //上面代码对数组进行对象解构。数组arr的0键对应的值是1,[arr.length - 1]就是2键,对应的值是3。方括号这种写法,属于“属性名表达式”
          let arr = [1, 2, 3];
          let { 0: first, [arr.length - 1]: last } = arr;
          first; // 1
          last; // 3
    
  • 相关阅读:
    Android 列表之分组ListView
    【转】容易忽视但是功能灰常强大的Java API
    onSaveInstanceState和onRestoreInstanceState的用处
    asp.net中url重写
    泛型数据类型转换
    关于 url重写后性能问题
    用CSS实现新闻轮播效果
    Java命名规范(简略)
    关于ngclass中添加多个样式类的解决方案
    python 常用标准库
  • 原文地址:https://www.cnblogs.com/tangge/p/10473727.html
Copyright © 2011-2022 走看看