ES6 学习总结&记录

#ES6 知识

零,ES6 介绍

ES6–ES2015
在 vue 中,Babel 是一个 JavaScript 编译器,主要用于将采用 ECMAScript 2015+语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。

ES6 环境搭建: webpack3.x 以上、Traceur

  1. 关于定义(声明)变量
    之前 var a=12; 现在 let a=12;
    作用域: 全局、 函数作用域、

    let 相当于之前的 var
    const 常量,定义好了不能改变

    let 注意: 1.没有预解析,不存在变量提升。
    在代码块内,只要 let 定义变量,在之前使用,都是报错。先定义完,再使用。

    块级作用域:{}
    if(){}
    for(){}
    while(){}

一,解构赋值

非常有用,特别在做数据交互时 ajax
let [a,b,c] = [1,5,6]

**注意:左右两边,解构和格式要保持一致

let json = {
        name: "linda",
        age: 18,
        job: "码农",
      };
      let { name: n, age, job: jobName } = json;

      解构时候可以给默认值
      let [aa, bb, cc = "暂无"] = ["aa", "bb"];
      //aa bb 暂无

一,字符串模板

关于字符串相关的一些东西:

  1. 优点,可以随意换行 ${变量名字}
    let str = 这个人叫${name},年龄为${age}岁;

  2. 字符串查找
    str.indexOf(要找的东西) 返回索引位置,没找到返回-1
    str.includes(要找的东西) 返回值 true/false

    作用:判断浏览器

  3. 字符串是否以 XX 开头 str.startsWith(检测的东西)

  4. 字符串是否以 XX 结尾 str.endsWith(检测的东西)

  5. 重复字符串: str.repeat(次数)

  6. 填充字符串
    往前填充 str.padStart(整个字符串长度,填充的东西)
    往后填充 str.padEnd(整个字符串长度,填充的东西)

二, 函数默认参数、箭头函数、剩余参数

1. 函数默认参数

   function show(a = "欢迎", b = "mmr") {
      console.log(a, b);
   }

   show();

2. 函数参数默认已经定义了,不能再使用 let const 生命

   function show2(a = 18) {
      let a = 44; //报错
      console.log();
      a;
   }
   show2();

3. 扩展运算符、reset 运算符 ...
   [1,2,3,4] ==> ...[1,2,3,4,5] ==>1,2,3,4,5
   1,2,3,4,5 ==> ...1,2,3,4,5 ==>[1,2,3,4]
   当剩余参数用的时候,...必须放到最后一个参数上

4. 箭头函数
   let show = () => 1; //左边参数,右边返回值

   0 => return 东西
   0 => {}
   注意:
   4.1.箭头函数中 this 问题,指的是定义函数所在的对象,不是在运行时所在的对象。

   4.2.箭头函数中,没有 arguments,用 ... 接收

   4.3.箭头函数 不能当 构造函数。

三,数组

ES5 里边新增的一些东西

循环:

1. for
2. while

3. arr.forEach() //—— 代替普通 for 循环
   ---arr.forEach(function (val, index, arr) {
   ------console.log(val, index, arr);
   ---});

4. arr.map() //——非常有用,做数据交互 “映射”
   正常情况下,需要配合 return,返回一个新的数组
   若是没有 return,相当于 forEach
   注意:平时只要用 map 一定要有 return 否则用 forEach 就行了
   map 可以重新整理数据结构 [{title:'aaa'}] -->[{t:'aaa'}]

5. arr.filter() //过滤,过滤一些不合格的元素,如果回调函数返回 true,就留下来

6. arr.some() //类似查找,数组里面某一个元素符合条件,就返回 true

7. arr.every() //every 数组里面 所有 元素都符合条件,才返回 true

他们可以接受两个参数:arr.forEach/map...(循环回调函数,this 指向谁)
---arr.forEach(function (val, index, arr) {
------console.log(this, val, index, arr); //this 是传入的第二个值 123
---}, 123);
——————————————————————————————————————————————————————————————————————————

8. arr.reduce() //求数组的和、阶乘--从左往右

9. arr.reduceRight()//从右往左

ES2017 新增一个运算符:幂
Math.pow(2,3) 现在变成 2\*\*3

=====================================================================

10. for...of 用来遍历属性
    arr.keys() 数组下标
    arr.entries()数组的某一项

=====================================================================

11. 扩展运算符
    let arr=[1,2,3]
    let arr2=[...arr]
    let arr3= Array.from(arr)

12. Array.from:
    作用:把类数组(获取一组元素、arguments..)对象转成数组

    个人观点:只要具备 length(比如字符串),就靠谱

13. Array.of 把一组值,转成数组 (很少用)
    let arr = Array.of("apple", "banana", "orange", "potato");
    console.log(arr);

14. Array.find 查找,找到第一个符合条件的数组成员,如果没有找到,返回 undefined

15. Array.findIndex 查找的是位置,没找到再返回-1

16. Arr.fill(填充内容,开始位置,结束位置-不包含)

在 ES2016 里边新增的:
arr.indexOf()
arr.includes() str.includes()

四,对象 JSON

  1. 对象简洁语法(相当有用)
   let json={
      a,
      b,
      showA(){ //一定注意,不要使用箭头函数
         return this.a;
      }
   }

   举例:
   new Vue({
      el: '#app',
      router,
      store,
      render: h => h(App)
   })
  1. Object.is() 用来比较两个值是否相等
    Object.is(NaN, NaN); //true
    (Object.is(+0, -0); //false

  2. Object.assign(): 用来合并对象
    可用于
    (1)复制一个对象;let obj = Object.assign({}, json, json2, json3);
    (2)合并参数 let arr2 = Object.assign([], arr);

   function ajax(option){
      let defaults={
         type:'get',
         header:'',
         data:{}
      }
      let json=Object.assign({},defaults,options)
   }

  1. Object.keys() 返回对象下标 组成的数组,(ES2017 引入的 )

  2. Object.entries() 返回对象的值 组成的数组,(ES2017 引入的 )

  3. Object.values() 返回对象下标和值 组成的数组,(ES2017 引入的 )

  4. 对象的扩展运算符 {…json}

五,类 class

  1. 面向对象,类: 属性、方法

  2. 函数模拟
    人:Person
    属性:name
    展示名字:showName

  3. ES5 之前:

    function Person(name, age) {
      this.name = name;
    }
    Person.prototype.showName = function () {}
  1. ES6 中变形
    class Person {
      constructor(name, age) {
         this.name = name;
         this.age = age;
      } //注意这里没有逗号,不要加逗号!!!!
      showName() {
      }
    }
写法二: const Person =class{}

扩展:[aaa] 变量作为方法名
  let aaa = "strive";
  let bbb = "method";

  class Person {
      [aaa + bbb]() {
        return "strivemethod方法执行了";
      }
     }
  1. 注意:
    (1) ES6 里面的 class/类 没有“提升/预解析”功能。
    ES5 中用函数模拟可以,默认函数提升。
    所以只能先声明 class Person 再 new Person()

    (2)ES6 里边的 this 比之前轻松多了

    this 在解构赋值中指向问题,矫正 this 方法
    解决 a: fn.call(this 指向谁,args1,args2…) //调用的同时矫正 this
    解决 b: fn.apply(this 指向谁,[args1,args2…]) //第二个参数是数组
    解决 c: fn.bind() //只矫正 this

    (3)Class 里边取值函数 getter 存值函数 setter

    (4)静态方法,就是类身上的方法,用 Person 自己去调用

  2. 类的继承:
    父类
    子类
    继承:

    ES6 之前 Person Student
    ES6 之后:extends
    class Student2 extends Person2 {}

  3. 通过继承写拖拽 DIV 功能

六,Promise 承诺、许诺

  1. 作用:解决异步回调问题
    传统方式,大部分用回调函数,事件

       new Promise(XX).then(res=>{
       console.log(res)
       }).catch(err=>{
          console.log(err)
       })
    
  2. Promise.resolve(‘aaa’):将现有的东西,转成一个 promise 对象,resolve 状态,成功状态
    等价于

    new Promise((resolve,reject)=>{
       resolve('aaa')
    })
    
  3. Promise.reject(‘aaa’):将现有的东西,转成一个 promise 对象,reject 状态,失败状态
    等价于

    new Promise((resolve,reject)=>{
       reject('aaa')
    })
    
  4. Promise.all([p1,p2,p3]):把 Promise 打包,扔到一个数组里边,打包完还是一个 Promise 对象
    必须确保,所有的 promise 对象,都是 resolve 状态,都是成功状态

    Promise.race([p1,p2,p3]):只要有一个成功(promise 对象是 resolve 状态),就返回

    用户登录–》用户信息

  5. 同步还是异步的问题
    Promise 是用来管理异步编程的,它本身不是异步的 ,promise 是同步代码

    promise 的回调 then,catch 是异步 :Promise 新建后立即执行,所以首先输出的是 XXX。然后,then 方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以 resolved 最后输出。

七,模块化

  1. JS 不支持模块化
    其他的比如 ruby 可以 require;pahton 可以用 import 来模块化

    在 ES6 之前,社区自己制定了一套模块规范:
    Commonjs 主要规定了服务端 比如 nodeJs 中要引用就用 require(‘http’)
    AMD 规范 比如 requireJS ,curlJS,
    CMD 规范 比如 seaJs

    ES6 出来,统一了服务端和客户端的模块规范
    import { xx } ddd

  2. 模块化:
    注意:需要放到服务器环境
    a) 如何定义模块?

       export const a=12;
       export {
          a as aa
       }
    

    b) 如何使用?
    import

    使用模块:

    import 特点:

    a)import 可以是相对路径,也可以是绝对路径
    import “http://code.jquery.com/jquery-3.3.1.js”;

    b)import 模块只会导入一次,无论你引入多少次

    c)import ‘./modules/1.js’; 如果这么用,相当于引入文件

    d)有提升效果,import 会自动提升到顶部,首先执行

    e)导出去的模块内容,如果里边有定时器更改,外面也会改动,不像 Common 规范缓存

    import() 类似 node 里边的 require,可以动态引入。默认 import{} 语法不能写到 if 之类的里边。

       import("../modules/1.js").then((res) => {
          console.log(res.a + res.b);
       });
    

    优点: 1.按需加载; 2.可以写到 if 中 3.路径也可以是动态的

    Promise.all([])

    ES2017 加 async await

    ‘use strict’ 以后可能默认就是严格模式 (模块化内部就是严格模式)

八,Symbol 和 generator

ES6 类
————————————————————————————
**数据类型: number string boolean Object undefined function 等
**新增类:symbol 用 typeof 检测出来数据类型 symbol

new Number(12)
new String()
new Array()

(一)symbol
symbol 使用情况一般

  1. 定义:
    let syml = Symbol(“aaa”);

  2. 注意:

    1.Symbol() 不能 new
    2.Symbol()返回的是一个唯一的值
    坊间传说,做一个 key,定义一些唯一的或者私有的一些东西。

    3.symbol 是一个单独的数据类型,就叫 symbol,基本类型

    4.如果 symbol 作为 key,用 for in 循环,出不来(私有)

————————————————————————————————————————————————————————————
箭头函数:()=>{}

(二)generator
generator 函数:
–生成器,
–解决异步、深度嵌套问题,async

  1. 语法:
      function \* show(){
         yield          //yield产出的意思
      }

      定义:
       fucntion * gen(){
          yield 'welcome';
          yield 'to';
          return '指环王';
      }

      //调用:
         let g1=gen();
         g1.next();  //{value: 'welcome', done: false}
         console.log(g1.next()); //{value: 'to', done: false}
         console.log(g1.next()); //{value: '指环王', done: true}

      //上述调用,手动调用,麻烦

      for..of 自动遍历 generator
         return的东西,它不会遍历

      generator 不仅可以配合 for..of
      还可以
         1. 解构赋值    let [a, ...b] = gen();
         2. 扩展运算符  ...gen()
         3. Array.from

      generator 结合axios数据请求
      -----------------------------
      异步:不连续,上一个操作没有执行完,下一个操作照样开始
      同步:连续执行,上一个操作没有执行完,下一个没法开始
      -----------------------------
      关于异步,解决方案:
         a)回调函数
         b)事件监听
         c)发布/订阅
         d)Promise对象

         ES2017,规定了 async

九,async await

读作"e think" 额甚克
在 nodeJs 中写一下

   读取文件 fs.readFile 三种方式
   注意,这一段执行要用node,在VSCODE底部的“终端”,执行 node .\async.js这种
   效果如下:
   PS D:\ProgramFile\vsCodeWorkspace\es6Demo\9,async-await> node .\async.js
   PS D:\ProgramFile\vsCodeWorkspace\es6Demo\9,async-await> node .\promise.js

   1.promise

   2.generator

   3.async

   async function(){//表示这个函数里边有异步的任务
      let result=await xx //表示后面的结果需要等待
   }


async 特点:

  1. await 只能放到 async 函数中
  2. 相比 generator 语义化更强
  3. await 后边可以是 promise 对象,也可以是数值、字符串、布尔值等(但 generator 后只能是 promise 对象)
  4. async 函数返回的是一个 promise 对象
  5. 只要 await 语句后面 Promise 状态变成 reject,那么整个 async 函数会中断执行

如何解决 async 函数中抛出错误,影响后续代码:
a) try{…}catch(e){}

      async function fn3() {
        try {
          await Promise.reject("出现问题了"); //如果放第一行,则后面的都不执行
        } catch (e) {}
        let a = await Promise.resolve("success");
        console.log("fn3", a);
      }

b)promise 本身 catch

个人建议大家,只要有 await,都 try catch 一下

   try {
      let f1 = await readFile("../data/a.txt"); //意思是等后边结果出来再往下走
      let f2 = await readFile("../data/b.txt");
      let f3 = await readFile("../data/c.txt");
   } catch (e) {}

* 举例: koa2 框架里很多这个 async await

十,Proxy 代理

  1. 扩展(增强)对象的一些功能
    比如:Vue
    Vue.config.keyCodes.down=40;

    Proxy 作用:
    比如 VUE 中拦截:预警、上报、扩展功能、统计、增强对象

  2. Proxy 是设计模式的一种,代理模式。
    let ob={
    name:‘Strive’
    };
    //您访问了 name
    obj.name

  3. 语法

   new Proxy(target,handler);
   let obj = new Proxy(被代理的对象,对代理的对象做什么操作)

   handler:{
      set(){}     //设置的时候干的事情
      get(){}     //获取干的事情
      deleteProperty(){}   //删除
      has(){}     //问你有没有这个东西--外面调用 'xxx' in obj 就会触发这个has(){}方法
      apply()     //调用函数处理
      ...
   }
  • 实现一个,访问一个对象身上的属性,默认不存在的时候给了 undefined,希望如果不存在就给一个错误(警告)信息

DOM.div()
DOM.ul()


set() 设置、拦截

*设置一个年龄,保证是整数,范围在 18-200

deleteProperty() 删除、拦截

has() 检测

apply() 拦截方法

Reflect.apply(调用的函数,this 指向,参数数组)

  1. Reflect 反射
    Object.xxx 语言内部方法,如:Object.defineProperty

    放到 Reflect 对象身上。

    通过 Reflect 对象身上直接拿到语言内部的东西。

    ‘assign’ in Object -> Reflect.has(Object,‘assign’);
    delete json.a -> Reflect.deleteProperty(json,‘a’);

	//目标对象
      const user = {
        name: "萧炎",
        age: 20,
        wife: {
          name: "熏儿",
          age: 19,
        },
      };

      //把目标对象变成 代理对象(Proxy)
      //参数1:user-->target目标对象;
      //参数2:handler-->处理器对象,用来监视数据,及数据的操作
      const proxyUser = new Proxy(user, {
        //获取目标对象的某个属性值
        get(target, prop) {
          console.log("get方法调用了"); //, target, prop
          return Reflect.get(target, prop); //通过反射对象Reflect,将XX反射出去
        },
        //修改目标对象的属性值/为目标对象添加新的属性
        set(target, prop, val) {
          console.log("set方法调用了");
          return Reflect.set(target, prop, val);
        },
        //删除目标对象上的某个属性
        deleteProperty(target, prop) {
          console.log("delete方法调用了");
          return Reflect.deleteProperty(target, prop);
        },
      });

      //通过代理对象 获取 目标对象中的某个属性值
      console.log("通过代理对象 获取", proxyUser.name);

      //通过代理对象 更新 目标对象中的某个属性值
      proxyUser.name = "唐三";

      console.log("通过代理对象 更新", user);

      //通过代理对象 向目标对象中 添加一个新的属性
      proxyUser.gender = "男";
      console.log("通过代理对象 添加", user);

      //通过代理对象 从目标对象中 删除一个属性
      delete proxyUser.name;
      console.log("通过代理对象 delete", user);

      //通过更新目标对象中的某个属性对象中的属性值
      proxyUser.wife.name = "小舞";
      console.log(user);

十一,set 和 weakset (新增的数据结构 类似数组)

  1. 数据结构 :数组、json、二叉树

  2. set 数据结构:类似数组,但是里边不能有重复值

   let arr = ['a','b','c'];

   let arr = new Array();

   set 用法:
      let setArray = new Set(['a','b']);

      setArr.add('a');     往setArr里添加一项
      setArr.delete('b');  删除一项
      setArr.has('a');     判断setArr里面有没有此值
      setArr.size;          个数
      setArr.clear();      清空


   for...of 循环

            a) for (let item of setArray) { console.log(item); }
            b) for (let item of setArray.keys()) { console.log(item); }
            c) for (let item of setArray.values()) { console.log(item); }
            d) for (let item of setArray.entries()) { console.log(item); }

            e) setArray.forEach((value, index) => { console.log(value, index); });

   let setArray3 = new Set().add("a").add("c"); //连接

   数组去重:
      let arr = [1, 2, 3, 4, 5, 6, 6, 2, 6, 7, 8, 9, 0, 5];
      let newArray = [...new Set(arr)];
      console.log(newArray);

   set数据结构变成数组:
      [...set]

   想让set使用数组的, map和filter循环:
      set = new Set([...set].map((val) => val * 2));
      set3 = new Set([...set3].filter((val) => val % 2 == 0));

   -------------------------------------------------
   let arr=[{},{}];
   new Set([]);      //存储放数组
   new WeakSet({})   //存储json,这种写法不靠谱。

   weakset 没有size,也没有clear,有add() has() delete()

   确认: 初始往里边添加东西是不行的,最好用add添加。
   总结:new Set()


十二,map 和 weakmap (新增的数据结构 类似 JSON)

  1. 类似 json,但是 json 的键值(key)只能是字符串
    map 的 key 可以是任意类型

使用:

   let map = new Map();
   map.set(key,value); 设置一个值

   map.get(key);     获取一个值

   map.delete(key);  删除一项

   map.has(key);     判断有没有

   map.clear();      清空

  1. 循环
      a) for (let item of map) { console.log(item); }
      b) for (let item of map.keys()) { console.log(item); }
      c) for (let item of map.values()) { console.log(item); }
      d) for (let item of map.entries()) { console.log(item); }

      map.forEach((value, key) => {
        console.log(value, key);
      });
  1. WeakMap(): key 只能是对象
    用处不大。

  2. 总结:
    Set 里边是数组,不重复,没有 key,没有 get 方法
    Map 对 json 功能增强,key 可以是任意类型值

十三,数字变化 和 Math 新增的东西

  1. 数字(数值)的变化:
    二进制(Binary): let a = 0b101010; 以 0b 开头的

    八进制(Octal): let a = 0o666; 以 0o 开头的

    十六进制: #ccc

    ————————————————————————————————
    Number(), parseInt(), parseFloat()
    ———————————————————————————————
    Number.isNaN(NaN) => true
    Number.isFinite(a) 判断是不是数字
    Number.isInteger(a) 判断是不是整数
    ————————————————————————————————
    Number.parseInt()
    Number.parseFloat()

  2. 安全整数
    安全整数:-(2^53 -1) 到 (2^53 -1) 包含 -(2^53 -1) 和 (2^53 -1)
    23 二的三次方;
    2
    53 二的 53 次方;
    Number.MAX_SAFE_INTEGER 最大安全整数
    Number.MIN_SAFE_INTEGER 最小安全整数

  3. Math

       Math.abs();    //返回任意数的绝对值
       Math.sqrt();     //求平方根
       Math.sin();       //正弦值
       Math.trunc(); 截取,只保留整数部分
          Math.trunc(4.56)--> 4
    
       Math.sign();  判断一个数是正数、负数、0
          Math.sign(-20) --> -1
          Math.sign(20) --> 1
          Math.sign(-0) --> 0
          Math.sign(0) --> 0
          其他值--> 返回 NaN
    
       Math.cbrt(); 计算一个数的立方根
    

十四,ES2018 (ES9)

  1. 命名捕获
    语法:(?<名字>)

       let str = "2018-03-20";
       let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
       let { year, month, day } = str.match(reg).groups;
       console.log(year, month, day);
    
    

    反向引用: \1 \2 $1 $2
    反向引用命名捕获: 语法:\k<名字>

       let reg = /^(?<wec>welcome)-\k<wec>$/;
       想要匹配的其实是 'welcome-welcome'
       \*\*reg 将 welcome 命名为了 wec,后面通过 \k<wec> 来代表这个 welcome
    

    let reg2 = /^(?welcome)-\k-\1$/;
    匹配:“welcome-welcome-welcome”

    替换: $<名字>

    let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
    str = str.replace(reg, "$<month>/$<day>/$<year>");
    console.log(str);
    
    //用回调函数
    str = str.replace(reg, (...args) => {
          console.log(...args);
          //2018-03-20 2018 03 20 0 2018-03-20 {year: '2018', month: '03', day: '20'}
          let { year, month, day } = args[args.length - 1];
    
          return `${day}/${month}/${year}`;
       });
       console.log(str); //20/03/2018
    
    
  2. dotAll 模式 s ,指的是.能匹配所有的模式
    之前 ‘.’ 在正则里表示匹配的是任意东西,但是不包括\n

    let reg=/\w+/gims;
    
    一个正则表达式中只会出现**一次**修饰符,修饰符一共有4个,分别是gims
    g 查找所有的匹配项,缺省时表示查找第一次匹配
    i 表示不区分大小写
    m和s都是根据换行符而言
    m 表示多行匹配,也就是说原本用来匹配字符串开头和结尾的^和$现在以换行符为基准,匹配每一行的开头和结尾
    s 表示.可以匹配换行符,而原本的.是不包括换行符的
    
  3. 标签函数
    fucntion fn(){}
    fn() 这样调用就是普通函数

    fnaaa //标签函数的使用

  • 31
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值