ES6学习笔记1

      /**

      let: 变量
      1.同一作用域下不能重复声明
      2.作用域: 全局作用域 和 块级作用域 {}
      3.不进行预解析


      const:常量
      1.声明必须赋值
      2.声明object类型 不能改的是引用地址


      块级作用域 {}


      解构赋值:(可迭代对象)
      1.怎么快速交换a,b的值
      let a = 0;
      let b = 1;
      [a, b] = [b, a];

      2.字符串的解构赋值
      let str = "abc";
      let [e, f] = str;  // a c

      3.数字的解构赋值
      let num = 123;
      let [c, d] = num; // 报错 num is not iterable


      展开运算符:
      1.
      let arr1 = [1, 2, 3, 4]
      let arr2 = ["a", "b", ...arr1, "c", "d"]   // ["a", "b", 1, 2, 3, 4, "c", "d"]

      2.剩余参数
      let [a, b, ...c] = arr1;
      console.log(a, b, c) // 1, 2, [3, 4]

      3.避免对象修改的是同一引用地址
      let obj = {a:1}
      let obj2 = {...obj}


      Set对象
      构造函数 用来构建某一类型的对象 对象的实例化
      let arr = [1, 2, 3, 4, 1, 2, "a"]
      let s = new Set(arr)  // 参数:数组 or 类数组, 去重
      arr = [...s]

      s.size() // 数值的个数 ==> length
      s.clear() // 清空
      s.delete("a") // 删除某一项
      s.add(6).add('b') //  添加某一项,返回set对象,支持链式
      s.has("a") //  是否包含某一项


      Map对象
      let arr = [
        ["a", 1],
        ["b", 10],
        ["c", 100]
      ]

      let m = new Map(arr)
      m.get(key);  //取值
      m.set(key, value); // 添加


      函数的扩展
      1.箭头函数
      2.不定参数 arguments
      function fn() {
        console.log(arguments)
      }

      fn(1,2)

      const fn1 = () => {
        console.log(arguments) // 报错,箭头函数没有不定参数,解决方法:rest参数
      }

      const fn1 = (...arg) => {
        console.log(arg)   // rest参数
      }

      3.this问题
      箭头函数本身没有this,调用箭头函数的this时,指向的是其声明时所在的作用域的this

      4.参数默认值




      数组的新增方法:
      1.构造函数下的方法
      1.1 Array.form()  把一个类数组转换成真正的数组,接收三个参数:类数组、遍历回调函数、this指向

      {
        let lis = document.querySelectorAll("#list li");
        let arr = [];
        lis = Array.form(lis, function(item, index) {
          console.log(item, index, this);
          return index;
        }, arr);

        console.log(lis)
      }


      1.2 Array.of() 将参数转成一个数组
      {
        Array.of(1, 2, "a", "b")    // [1, 2, "a", "b"]
      }

      1.3 Array.isArray() 检测数据是否是个数组


      2.数组对象本身的方法
      let arr = new Array();
      2.1 arr.find()  // 查找数组中满足要求的第一个元素, 返回具体的值
      参数1:回调函数
      参数2:回调函数的this指向

      {
        let arr = ["a", "b", "c"]
        let arr = [1, 2, 3, 4]
        let val = arr.find((item, index) => {
          if(item >= 3) {
            return true
          }
        });
        console.log(val)  // 3
      }

      2.2 arr.findIndex()  // 返回索引

      2.3 arr.flat()  // 扁平化多维数组。传参:层级,或者Infinity,不传默认一层
      {
        const arr =[
          ["小明", 18],
          [["ew","ewrwer"], [343, 34324]]
        ]

        arr.flat()
      }


      2.4 arr.flatMap()  //与深度为1的flat作用几乎相同

      {
        let arr = [
          ["小明", "34"]
          ["xiaohua", "12"]
        ]

        let newArr = arr.flatMap((item, index) => {
          console.log(item, index)

          return item;
        })

        console.log(newArr)
      }

      2.5 arr.fill()  // 填充
      {
        let arr = [0, 1, 2, 3, 4]
        arr.fill("a", 1, 3)  // 从索引1开始填充,索引3截止  [0, "a", "a", 3, 4], 默认值是arr.length
      }

      2.6 arr.includes()
      {
        let arr = ["a", "b", "c"]
        arr.includes("c", 2)   // true 从索引2开始检索
      }



      字符串新增的方法
      1.includes
      2.startsWith('ab', 2)   // 从索引2开始查找ab开始的字符串,返回布尔值
      3.endsWith()  // 以xx结束
      4.repeat()   // 传入数字,重复n次
      5.模板字符串



      对象新增的方法
      1.简洁表示法
      let a = 2;
      let b = 232;
      let obj = {
        a,
        b,
        c() {
          // ...
        }
      }

      2.属性名表达式(给属性名赋值)
      let name = '小明';
      let obj = {
        [name]: 111
      }

      console.log(obj)
      // let obj = {
      //   '小明': 111
      // }

      3.  Object.assign()
      4.  Object.is(value1, value2)  // 判断两个值是否是相同的值

      console.log(+0 === -0)          // true
      console.log(Object.is(+0, -0))  // false
      console.log(Object.is(1, "1"))  // false
      console.log(Object.is(NaN, NaN))  // true

      两个值都是 undefined
      两个值都是 null 或者都是 false
      两个值是 由相同个数的字符 按照相同的顺序 组成的字符串
      两个值指向同一个对象
      两个值都是 数字 并且
                      都是 +0
                      都是 -0
                      都是 NaN


      babel

      迭代器
      1.迭代协议:规定了迭代与实现的逻辑
      2.迭代器:具体的迭代实现逻辑
      3.迭代对象:可被迭代的对象-实现了[Symbol.iterator]方法
      4.迭代语句
      for ... in: 以原始插入的顺序迭代对象的可枚举属性
      for ... of: 根据迭代对象的迭代器具体实现迭代对象数据

      5.迭代器实现原理
      5.1
      obj[Symbol.iterator] = function() {
        return {
          next() {
            return {
              value: '11', // 循环过程中的值
              done: false    // true循环结束 false循环未完成
            }
          }
        }
      }


      5.2 for...in 遍历数组,拿到的是下标
      let arr = ["a", "b", "c"]
      for(let attr in arr) {
        console.log(attr)  // 0 1 2
      }


      5.3 for...of 遍历数组,拿到的是value
      let arr = ["a", "b", "c"]
      for(let attr of arr) {
        console.log(attr)  // a b c
      }


      5.4 for...in 遍历对象,拿到的是属性名
      let obj = {
        a: '2323',
        b: 'wewr',
      }
      for(let attr in obj) {
        console.log(attr)  // a b
      }


      5.5 for...of 遍历对象,报错
      let obj = {
        a: '2323',
        b: 'wewr',
      }
      for(let attr of obj) {
        console.log(attr)  // Uncaught TypeError: obj is not iterable
      }


      可迭代对象不可迭代对象,区别在于是否定义了迭代器 Symbol.iterator
      let obj = {
        a: 1,
        b: 2,
        c: 3,
      }
      for(let val of obj) {
        // 迭代协议(条件)
        let values = Object.values(obj);
        let index = 0;

        obj[Symbol.iterator] = function() {
          return {
            next() {
              if(index >= values.length) {
                return {
                  done: ture    // true循环结束
                }
              } else {
                return {
                  done: false,
                  value: values[index++]
                }
              }
            }
          }
        }
      }


    // 撸一下,手动模拟过程(for...of相当于把此过程执行了一遍,不停的调用next方法)
    let values = obj[Symbol.iterator]();
    values.next()   // {done: false, value: 1}
    values.next()   // {done: false, value: 2}
    values.next()   // {done: false, value: 3}
    values.next()   // {done: true}




    Generator 函数
    在形式上,Generator是一个普通函数,但是有两个特征。
    一是,function命令与函数名之间有一个星号
    二是,函数体内部使用yield语句,定义遍历器的每个成员,即不同的内部状态

    function*fn() {
      yield 1;
      yield 2;
      yield 3;
    }

    let f = fn();
    // console.log(f); // 返回一个Generator函数
    // f.next();  // {value: 1, done: false}
    for(let val of f) {
      console.log(val)  // 1 2 3
    }

    // 改写
    function*fn() {
      yield new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log(1);
          resolve("第一个yeild执行完毕");
        }, 200);
      });

      yield new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log(1);
          resolve();
        }, 200);
      });

      yield new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log(1);
          resolve();
        }, 200);
      });
    }

    co(fn);

    function co(fn) {
      let f = fn();
      next();

      function next() {
        let result = f.next();
        if(!result.done) {
          // 上一个异步走完了,再执行下一个异步
          result.value.then((info) => {
            console.log(info)
            next();
          })
        }
      }
    }
原文地址:https://www.cnblogs.com/yhquan/p/14545591.html