ES6特性一览

目录

class类

Module

promise

Async

箭头函数

let和const

字符串方法

数组方法

对象方法

...操作符

Set


class类

  • constructor():构造函数,new命令生成实例时自动调用
  • extends:继承父类
  • super:新建父类的this
  • static:定义静态属性方法
  • get:取值函数,拦截属性的取值行为
  • set:存值函数,拦截属性的存值行为

私有属性方法

const name = Symbol("name");
const print = Symbol("print");
class Person {
    constructor(age) {
        this[name] = "Bruce";
        this.age = age;
    }
    [print]() {
        console.log(`${this[name]} is ${this.age} years old`);
    }
}

继承混合类

function CopyProperties(target, source) {
    for (const key of Reflect.ownKeys(source)) {
        if (key !== "constructor" && key !== "prototype" && key !== "name") {
            const desc = Object.getOwnPropertyDescriptor(source, key);
            Object.defineProperty(target, key, desc);
        }
    }
}
function MixClass(...mixins) {
    class Mix {
        constructor() {
            for (const mixin of mixins) {
                CopyProperties(this, new mixin());
            }
        }
    }
    for (const mixin of mixins) {
        CopyProperties(Mix, mixin);
        CopyProperties(Mix.prototype, mixin.prototype);
    }
    return Mix;
}
class Student extends MixClass(Person, Kid) {}

Module

  • export:规定模块对外接口
    • 默认导出export default Person(导入时可指定模块任意名称,无需知晓内部真实名称)
    • 单独导出export const name = "Bruce"
    • 按需导出export { age, name, sex }
    • 改名导出export { name as newName }
  • import:导入模块内部功能
    • 默认导入import Person from "person"
    • 整体导入import * as Person from "person"
    • 按需导入import { age, name, sex } from "person"
    • 改名导入import { name as newName } from "person"
    • 自执导入import "person"
    • 复合导入import Person, { name } from "person"

模块方案

  • CommonJS:用于服务器(动态化依赖)
  • AMD:用于浏览器(动态化依赖)
  • CMD:用于浏览器(动态化依赖)
  • UMD:用于浏览器和服务器(动态化依赖)
  • ESM:用于浏览器和服务器(静态化依赖)

加载实现

  • 传统加载:通过<script>进行同步或异步加载脚本
    • 同步加载:<script src=""></script>
    • Defer异步加载:<script src="" defer></script>(顺序加载,渲染完再执行)
    • Async异步加载:<script src="" async></script>(乱序加载,下载完就执行)
  • 模块加载<script type="module" src=""></script>(默认是Defer异步加载)

promise

  • 定义:包含异步操作结果的对象
  • 状态
    • 进行中pending
    • 已成功resolved
    • 已失败rejected
  • 特点
    • 对象的状态不受外界影响
    • 一旦状态改变就不会再变,任何时候都可得到这个结果
  • 声明:new Promise((resolve, reject) => {})
  • 出参
    • resolve:将状态从未完成变为成功,在异步操作成功时调用,并将异步操作的结果作为参数传递出去
    • reject:将状态从未完成变为失败,在异步操作失败时调用,并将异步操作的错误作为参数传递出去
  • 方法
    • then():分别指定resolved状态rejected状态的回调函数
      • 第一参数:状态变为resolved时调用
      • 第二参数:状态变为rejected时调用(可选)
    • catch():指定发生错误时的回调函数
    • let p = new Promise(function(resolve, reject) {
        // 封装异步操作,传入成功时执行的resolve函数和失败执行的reject函数
        $.ajax({
          url: "https://xxx",
          success(data) {
            resolve("success", data);
            // 成功的话执行resolve函数,并传入一个状态和对应的数据,在后面then的时候调用
          },
          error(data) {
            reject("error", data);
            // 失败执行reject函数,在后面catch的时候调用
          }
        });
      });
      
      // 在这里进行异步操作的回调处理
      p.then(function(status, data) {
        // 成功时的回调函数,相当于此时执行resolve方法
        console.log(status, ":", data);
      }).catch(function(status, data) {
        // 失败时的回调函数,相当于此时执行reject方法
        console.log(status, ":", data);
      });

    • Promise.all():将多个实例包装成一个新实例,返回全部实例状态变更后的结果数组(齐变更再返回)
      • 入参:具有Iterator接口的数据结构
      • 成功:只有全部实例状态变成fulfilled,最终状态才会变成fulfilled
      • 失败:其中一个实例状态变成rejected,最终状态就会变成rejected
    • new Promise.all([
          // 传入一个包含多个异步操作的数组
          $.ajax({ url: "https://xxx", dataType: "json"}),
          $.ajax({ url: "https://yyy", dataType: "json"}),
          $.ajax({ url: "https://zzz", dataType: "json"}),
      ]).then(
          // 通过then方法调用后续操作,分别传入一个成功和失败的处理方法
          ([data1, data2, data3]) => {
              // 返回的数组分别是data1,data2,data3,通过结构方式接受
              console.log(data1, data2, data3);
          }, res => {
              console.log("失败");
          })

    • Promise.race():将多个实例包装成一个新实例,返回全部实例状态优先变更后的结果(先变更先返回)
      • 入参:具有Iterator接口的数据结构
      • 成功失败:哪个实例率先改变状态就返回哪个实例的状态
    • Promise.race([
          $.ajax({ url: "https://xxx", dataType: "json"}),
          $.ajax({ url: "https://yyy", dataType: "json"}),
          $.ajax({ url: "https://zzz", dataType: "json"}),
      ]).then(
          (data) => {
              // 只对第一个完成的操作进行回调
              console.log(data);
          }, res => {
              console.log("失败");
          })

    • Promise.resolve():将对象转为Promise对象(等价于new Promise(resolve => resolve()))
      • Promise实例:原封不动地返回入参
      • Thenable对象:将此对象转为Promise对象并返回(Thenable为包含then()的对象,执行then()相当于执行此对象的then())
      • 不具有then()的对象:将此对象转为Promise对象并返回,状态为resolved
      • 不带参数:返回Promise对象,状态为resolved
    • Promise.reject():将对象转为状态为rejected的Promise对象(等价于new Promise((resolve, reject) => reject()))

Async

  • 声明
    • 具名函数:async function Func() {}
    • 函数表达式:const func = async function() {}
    • 箭头函数:const func = async() => {}
    • 对象方法:const obj = { async func() {} }
    • 类方法:class Cla { async Func() {} }
  • await命令:等待当前Promise对象状态变更完毕
    • 正常情况:后面是Promise对象则返回其结果,否则返回对应的值
    • 后随Thenable对象:将其等同于Promise对象返回其结果
  • async function aaa() {
        console.log(0);
        let x = await $.ajax({ url: "https://xxx", dataType: "json" }, function(data) { console.log(data); })
        // x接收异步操作返回的数据
        // 由于这里使用了await等待,所以在该步会等待异步操作执行
        // 如果异步操作失败成功则执行后续步骤,否则不会进行后面的操作
        console.log(1);
        let y = await $.ajax({ url: "https://yyy", dataType: "json" }, function(data) { console.log(data); })
        console.log(2);
        let z = await $.ajax({ url: "https://zzz", dataType: "json" }, function(data) { console.log(data); })
        console.log(3);
    }

  • 错误处理:将await命令Promise对象放到try-catch中(可放多个)
  • async function aaa() {
      console.log(0);
      try{
        let x = await $.ajax({ url: "https://xxx", dataType: "json" }, function(data) { console.log(data); })
        console.log(x);
      } catch(e) {
        // 捕捉失败的请求
        console.log(e);
      }
    }

重点难点

  • Async函数返回Promise对象,可使用then()添加回调函数
  • function ajax() {
      // 封装成Promise对象
      return new Promise((resolve, reject) =>
        $.ajax({
          url: "https://xxx",
          dataType: "json",
          success(data) {
            // then里调用
            resolve(data);
          },
          error(e) {
            // 失败时catch捕捉
            reject(e);
          }
        })
      );
    }
    
    async function aaa() {
      console.log(0);
      let x = await ajax().then(data => data).catch(e => false);
      // 异步成功则只执行then,返回data,失败则捕捉并返回false
      console.log(x);
    }

  • 内部return返回值会成为后续then()的出参
  • 内部抛出错误会导致返回的Promise对象变为rejected状态,被catch()接收到
  • 返回的Promise对象必须等到内部所有await命令Promise对象执行完才会发生状态改变,除非遇到return语句抛出错误
  • 任何一个await命令Promise对象变为rejected状态,整个Async函数都会中断执行
  • 希望即使前一个异步操作失败也不要中断后面的异步操作
    • await命令Promise对象放到try-catch
    • await命令Promise对象跟一个catch()
  • await命令Promise对象可能变为rejected状态,最好把其放到try-catch
  • 多个await命令Promise对象若不存在继发关系,最好让它们同时触发
  • await命令只能用在Async函数之中,否则会报错
  • 数组使用forEach()执行async/await会失效,可使用for-ofPromise.all()代替
  • 可保留运行堆栈,函数上下文随着Async函数的执行而存在,执行完成就消失

箭头函数

1.没有自己的this,导致内部的this就是外层代码块的this

2.因为没有this,因此不能用作构造函数

a = {
    name: "aaa",
    fn: function() {
        console.log(this, this.name + "bbb")
        // 使用function定义的this会绑定到当前对象,因此输出为当前对象a和"aaabbb"
    },
    fn1: () => {
        console.log(this, this.name + "bbb")
        // 箭头函数使得this绑定在window对象,因此输出为window对象和"bbb"
    }
}
a.fn()
a.fn1()

let和const

const:声明常量,必须立即赋值

let:声明变量

特点:

  • 不允许重复声明
  • 未定义就使用会报错:const命令let命令不存在变量提升
  • 暂时性死区:在代码块内使用const命令let命令声明变量之前,该变量都不可用

字符串方法

includes:判断字符串是否存在于其中

"abc".includes('a')
// true
"abc".includes('d')
// false

startsWith:判断字符串是否以其开头,endsWith:结尾

"abc".startsWith('a')
// true
"abc".startsWith('b')
// false

repeat:将字符串复制成原来的几倍

"abc".repeat(3)
// "abcabcabc"

数组方法

for of:遍历数组

a = [1,2,3,4,5]
a.forEach((item, index) => {console.log(item, index)})
// 循环输出:1 0、2 1、...

forEach:遍历数组(使用throw中断循环)

var arr = ['a','b','c','d'];
for(var item of arr){	
    console.log(item);
}
//输出a,b,c,d

map:对数组数据进行统一操作

a = [1,2,3,4,5]
a.map(function(item){return item>=3})
// 统一操作判断每个数据是否大于等于3,[false, false, true, true, true]
// 由于上面的函数符合一个参数,且只有一条return语句,因此可以简写如下:
// 简写后:a.map(item=>item>=3)
// 这里容易看混掉的是第一个=>是代表箭头函数,第二个=>代表大于等于运算符


a.map(function(item, index){return [item, index]})
// [[1,0],[2,1],[3,2],[4,3],[5,4]]

reduce:对整个数组进行循环某运算,其下有三个参数为:tmp/item/index,分别代表上一次操作返回的结果(第一次默认为数组的第一个数)、下一个传入的值(即数据的下一个数)、循环的索引

a = [1,2,3,4,5]
a.reduce(function(tmp, item, index) {
    console.log(tmp, item);
    return tmp + item;
    // 返回结果为当前数和下一个数的求和
})
// 最后的结果为15

filter:根据条件过滤数据

a = [1,2,3,4,5]
a.filter(item => item%2==0)
// 返回所有偶数,结果为[2, 4]

some:循环判断数组中是否存在满足条件的数据,只要有一个满足就返回true

a = [1,2,3,4,5]
a.some(item=>item>=3)
// 有大于等于3的数,返回true

every:循环判断数组中是否全部满足条件,是则返回true

a = [1,2,3,4,5]
a.every(item=>item>=3)
// 有不大于等于3的数,返回false

对象方法

for in:遍历对象数组的键值

var obj={
    name:'abc',
    age:13
}
 
for(var key in arr){
    console.log(key+': '+arr[key]);	
}
//name: abc
  age: 13

Object.keys():将对象的所有键以数组形式输出

o = {a:1, b:2, c:3}
Object.keys(o)
// ["a", "b", "c"]

Object.values():将对象的所有值以数组形式输出

o = {a:1, b:2, c:3}
Object.values(o)
// [1, 2, 3]

Object.entries():将对象的所有键和值以数组形式输出,数组中的子元素是长为2的数字,分别为键和值

o = {a:1, b:2, c:3}
Object.entries(o)
// [Array(2), Array(2), Array(2)]
Object.entries(o)[0]
// ["a", 1]

Object.assign():合并对象(浅拷贝),返回原对象

 Object.is():对比两值是否相等

...操作符

1.将数组展开传入

function test(a, b, c) {
    console.log(a + b + c);
}
test(...[1, 2, 3])
// 将数组展开成1, 2, 3赋值给a, b, c

2.数组拼接

a = [1,2,3]
b = [4,5,6]
[...a, ...b]
// [1, 2, 3, 4, 5, 6]

3.对象拼接

a = {name: 111, pwd: 222}
{...a, b:1}
// 通过对象{b: 1}存放...a,结果为:{name: 111, pwd: 222, b: 1}

Set

成员值都是唯一且没有重复的值

  • 去重字符串:[...new Set(str)].join("")
  • 去重数组:[...new Set(arr)]Array.from(new Set(arr))
  • 集合数组
    • 声明:const a = new Set(arr1)const b = new Set(arr2)
    • 并集:new Set([...a, ...b])
    • 交集:new Set([...a].filter(v => b.has(v)))
    • 差集:new Set([...a].filter(v => !b.has(v)))
  • 映射集合
    • 声明:let set = new Set(arr)
    • 映射:set = new Set([...set].map(v => v * 2))set = new Set(Array.from(set, v => v * 2))

参考:ES6+ 特性整理 - 简书

参考:掘金

猜你喜欢

转载自blog.csdn.net/Lc_style/article/details/106338815