1、JavaScript vs ECMAScript

  1. **Js具备三块内容 **1、文档模型DOM 2、浏览器BOM 3、核型规范ECMAScript<br />**ES6 泛指2015年之后的新版本规范,主要做的事情是**<br /> 1、解决原有语法问题和不足(let const <br /> 2、对原有语法进行增强 (解构、展开、参数默认值、模版字符串)<br /> 3、全新的对象、方法、功能 ProxyPromiseObject.assignReflectGenerator函数)<br /> 4、全新的数据结构和类型 (SetMapSymbolArrayBuffer)

2、块级作用域、模版字符串

为什么需要块级作用域:
1、let、const引用暂时性死区概念,规避var变量提升出现的一些
2、引入块级作用域,取代IIFE匿名函数自执行(引发闭包造成不必要的内存泄漏)
3、变量声明与window对象脱离
模版字符串:

  1. let time = hour + '时' + min + '分'
  2. let time = `${hour}时${min}分`

3、对象与数组的解构、rest操作符

  1. let [x, y = 'b'] = ['a']; // x='a', y='b'
  2. let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
  3. let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
  4. let [head, ...tail] = [1, 2, 3, 4]; //head // tail // [2, 3, 4]

4、函数进阶(箭头函数、默认参数)

es6之前不能直接在函数中添加默认参数只能通过变通的方式

  1. function test(num){
  2. num = num || 123
  3. }
  4. =>
  5. function log(x, y = 'World') {
  6. console.log(x, y);
  7. }

箭头函数出现的意义
1、简化写法,表达更简洁,简化回调函数,简化返回值写法
2、普通函数内部的this是谁调用指向谁(运行时),箭头函数是没有自己的this,内部this是定义时所在的作用域的this
3、箭头函数没有自己的this,所有无法new实例,不可以使用arguments,可以使用rest替代,不能用yield命令,不能用作generator函数,也不能使用call、bind、apply去改变this

使用箭头函数的情况: 1、异步回调中 2、带有定时器的函数中
不建议使用箭头函数的情况 1、对象中属性是方法 2、动态this如dom操作点击按钮使用当前this 3、负责的读写操作增加可读性的时候**

5、对象和数组的扩展用法

扩展运算符

  1. console.log(...[1, 2, 3])
  2. // 1 2 3

数组新增了Array.of 、 Array.from 、copyWithin 、 find() 、findIndex() 、fill()、includes 、flat 、flatMap


6、Proxy、Reflect、Map、Set、Symbol

Proxy:

  1. var proxy = new Proxy(target, handler);

Reflect:
Reflect 可以用于获取目标对象的行为,它与 Object 类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与 Proxy 是对应的

Map、Set:
使用Set查看当前页面有多少div元素
set、get、has、clear、delete

  1. let set = new Set();
  2. document.querySelectorAll('div').forEach(div=>set.add(div))
  3. set.size()
  1. const map = new Map([
  2. [1, 'one'],
  3. [2, 'two'],
  4. [3, 'three'],
  5. ]);
  6. [...map.keys()]
  7. // [1, 2, 3]
  8. [...map.values()]
  9. // ['one', 'two', 'three']
  10. [...map.entries()]
  11. // [[1,'one'], [2, 'two'], [3, 'three']]
  12. [...map]
  13. // [[1,'one'], [2, 'two'], [3, 'three']]

Symbol
代表独一无二的数据结构

  1. let s = Symbol();
  2. typeof s
  3. // "symbol"

7、for…of 、 迭代器模式、生成器函数

创建迭代过程

const items = [“zero”, “one”, “two”]; const it = itemsSymbol.iterator; it.next(); >{value: “zero”, done: false} …

for…of 可迭代类型 Map、Set、Array、String、DOM
for…of 不可迭代对象(..is not iterable),因为没有Iterator接口, 遍历的item为value,相当于Object.value方法
for…in 对象数组都可以 遍历的item为key 相当于Object.keys方法,所有多用于对象,数组是索引

8、ES Modules 模块系统

在 ES6 前, 实现模块化使用的是 RequireJS 或者 seaJS
ES6 的模块化分为导出(export) @与导入(import)两个模块。
特点:
模块中可以导入和导出各种类型的变量
每个模块都有自己的上下文,不会污染全局作用域
每一个模块只加载一次(是单例的)

9、Promise

Promise 是异步编程的一种解决方式
特点:padding、rejected、resolved三种状态,通过.then 获取回调结果
缺点:一旦执行无法取消,无法知道padding状态具体情况,不用回调无法感知异常
总结:链式调用的特点一定程度的解决了传统异步回调地狱写法的复杂和不可读性,没有从根本解决,仍然需要通过.then获取回调结果

10、decorator

介绍: Decorator,即装饰器,就是函数,用来动态的扩展对象功能的设计理论
用法:

  1. // a soldier hasn`t anything
  2. class soldier{}
  3. // he get a decoration
  4. function strong(target){
  5. target.Ak = true
  6. }
  7. // use it
  8. @strong
  9. class solider{}
  10. // so the solider has Ak
  11. solider.Ak // true

使用装饰器优点:

  • 代码可读性变强了,装饰器相当于一个注释
  • 在不改变原有代码的情况下,对原来功能进行了扩展

使用场景

  • react-redux

    1. class MyReactComponent extends React.Component {}
    2. export default connect(mapStateTopProps,mapDispatchToProps)(MyReactComponent)
    3. =>
    4. @connect(mapStateTopProps,mapDispatchToProps)
    5. export default class MyReactComponent extends React.Component {}
  • mixins

    1. function mixins(...list){
    2. return function(targrt){
    3. Object.assing(targrt,prototype,...list)
    4. }
    5. }
    6. // 使用
    7. const Foo = {
    8. foo(){ console.log('foo') }
    9. }
    10. @mixins(Foo)
    11. class MyClass{}
    12. let obj = new MyClass();
    13. obj.foo() // 'foo'


    11、ES2016-ES2020(ES7-ES11)特性一览

    ES2016(ES7)

    数组的扩展

    1. Array.prototype.includes(searchElement, fromIndex)
    2. const arr = ['es6', 'es7', 'es8', 'es9', 'es10']
    3. console.log(arr.includes('es7', 1)) // true,从下标1开始查找

    数值扩展:幂运算符号 **
    1. Math.pow(x,y)
    2. x**y

    ES2017(ES8)

    1、Async/await ```javascript async function timeout () { return new Promise((resovle, reject) => { setTimeout(() => {

    1. // resovle('success')
    2. reject('error')

    }, 1000) }) }

async function main () { try { const res = await timeout() console.log(res) } catch (e) { console.log(e) } }

main()

  1. ```json
  2. async function request(url) {
  3. const data = await axios.get(url)
  4. console.log(data)
  5. }

2、对象的扩展 Object.values(),Object.entries()

3、对象属性描述:Object.getOwnPropertyDescriptors()
  1. let obj = {
  2. a: 1,
  3. b: 2
  4. }
  5. const res = Object.getOwnPropertyDescriptors(obj,a) //{ value: 1, writable: true, enumerable: true, configurable: true }


4、字符串扩展String.prototype.padStart / padEnd

ES2018(ES9)

1、异步迭代 for await of

  1. function getPromise(time){
  2. return new Promise(resolve=>{
  3. setTimeout(()=>{
  4. resolve(time)
  5. },time)
  6. })
  7. }
  8. let arr = [getPromise(1000), getPromise(2000), getPromise(3000)];
  9. let main = async ()=>{
  10. for await(let item of arr){
  11. console.log(item)
  12. }
  13. }
  14. main()
  15. // 1000
  16. // 2000
  17. // 3000

2、Promise.prototype.finally()

**

ES2019(ES10)

1、对象Object.formEntries() 将map和数组转化成对象
2、字符串扩展String.prototype.trimStart() 、String.prototype.trimEnd()
3、数组扩展 扁平化的方法 Array.prototype.flat 、Array.prototype.flatMap
4、Symbol扩展:Symbol.prototype.description

  1. let s = Symbol('imooc')
  2. console.log(s)
  3. console.log(s.description)
  4. Symbol(imooc)
  5. imooc

11、参考

阮一峰ES6