JS专题之ES6

215 阅读5分钟

es6.ruanyifeng.com/#docs/intro

1. 块级作用域

let和const

2. 变量的解构和赋值

数组,对象,字符串,数值,布尔,函数参数

3. 字符串的扩展

模板字符串,for…of…遍历器接口

4. 字符串的新增方法

实例方法(includes,startsWith,endsWith,repeat,padStart,padEnd)

5. 数值的扩展(共8种数据类型)

新增BigInt类型,原是Object(Array,Function,Date),String,Number,Boolean,Null,Undefined,Symbol

6. 函数的扩展:

  • 函数参数默认值
  • rest参数:…变量名,表现为一个数组参数。rest参数只能作为最后一个参数。
  • 箭头函数:简化回调函数,注意:(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
  • 尾调用优化

7. 数组的扩展

  • 扩展运算符...:内部使用for...of实现,用在数组/表达式将数数组转化为用逗号分隔的参数序列;由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。

  • a = [1,2,3] console.log(...a)//1 2 3 console.log([...a])//还原为[1, 2, 3]

    function a(){
    for (item in arguments){
    console.log(arguments[item])
    }
    }
    a.apply(null,[1,2,3])//ES5数组序列参数写法
    a(...[1,2,3])//ES6数组序列参数写法
    

用在字符串/实现了iterable接口的对象前结合[]将其转为真正的数组

console.log(...'hello')//h e l l o
console.log([...'hello'])// ["h", "e", "l", "l", "o"]
s = new Set('hello');
console.log(s)//{"h", "e", "l", "o"}
console.log(...s)//h e l o
console.log([...s])//["h", "e", "l", "o"]
  • 实例方法(includes,copyWithin,)

8. 对象的扩展

简略表示法,属性名表达式(使用中括号),

9. 对象的新增方法

Object.is,Object.assign

10. Set和Map数据结构

通过new生成。Set类似数组但无重复无序,Map类似对象但键名不限于字符串。

11. Proxy对象

在目标对象之前架设一层拦截,可以对外界的访问进行过滤和改写。New Proxy(target,{set: function (){},get: function (){}}),的set(使用Reflect.set)和get(使用Reflect.get)

12. Reflect对象

  • 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。
  • 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。
  • 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。
  • Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

13. Promise对象:异步操作

  • 异步(任务)编程的实践方案

  • Promise嵌套:内层的状态冒泡反馈给外层的状态

  • then方法返回的也是个promise实例,因此可以有链式写法;promise函数及then()方法指定的回调函数,如果运行中抛出错误,也会被catch()方法捕获,相当于有了try…catch…。

  • catch方法返回的也是个promise实例,可以捕获运行时错误,但如果没有写catch, Promise 内部的错误不会影响到 Promise 外部的代码的执行,通俗的说法就是“Promise 会吃掉错误”。

  • Promise.resolve():可以用于包装一个promise实例。

  • Promise.all():用于将多个Promise实例包装成一个新的promise实例。Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。注意,如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,走了自己的catch方法后传给Promise.all的将是catch的promise实例,那么就不会触发Promise.all()的catch方法,而是then方法,相当于自己消化了rejected。

  • Promise.race():同样用于将多个Promise实例包装成一个新的promise实例,区别在于只要有一个状态改变即改变状态并只传这一个回调值。

    const p =
    Promise.race([  fetch('/resource-that-may-take-a-while'),
    
      new Promise(function (resolve, reject) {
    
        setTimeout(() => reject(new
    Error('request timeout')), 5000)
    
      })
    
    ]);
    
    p
    
    .then(console.log)
    
    .catch(console.error);
    
  • Promise.allSettled():接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束。

  • Promise.any():接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

  • Promise.try:让同步函数同步执行,异步函数异步执行

14. generator/yield

内部封装了多个状态;返回一个遍历器Iterator对象。使用next方法使指针移向下一个状态。yield暂停执行标记;next()恢复执行,返回的是一个对象,两个对象属性value和done标记。

15. async/await

  • generator函数的语法糖,将generator函数和其执行器包装在一个函数里

  • 返回promise对象;

  • 配合try…catch…使用,像写同步代码一样使用。

  • 正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。

  • 多次重复尝试

    const
    superagent = require('superagent');const
    NUM_RETRIES = 3;
    
    async
    function test() {
    
      let i;
    
      for (i = 0; i < NUM_RETRIES; ++i) {
    
        try {
    
          await
    superagent.get('http://google.com/this-throws-an-error');
    
          break;
    
        } catch(err) {}
    
      }
    
      console.log(i); // 3
    
    }
    
    test();
    

16. class

生成实例对象的传统方法是通过构造函数(function),可以把function函数统一看成构造函数。class只是一种新的语法糖。ES5的构造函数对应于ES6中class的构造方法constructor。类的数据类型就是函数,类本身就指向构造函数(prototype.constructor)。构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。

17. 模块

  • ES6使用exports和import实现静态加载也叫编译时加载而不是运行时加载。浏览器加载 ES6 模块,也使用
  • CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

18. 函数管理,函数同步异步区分,函数异常管理: