当前位置: 首页 > 工具软件 > esnext > 使用案例 >

wsjls-zw:14、ES6、ESNext规范

东方宜
2023-12-01

ES6 ES2015是主要的版本

ES2018 增加了rest和spread语法

ES2020 第11版

ES的下一个版本是ESnext

## ES6及以后新增常用API

#### let const

for (var i=0;i<=3;i++) {

  setTimeout(function(){

    console.log(i)

  },10)

}

原因:

1、var 全局变量,只有一个i

2、setTimeout,下一轮事件循环的时候执行,i=4;console.log(4)

for (let i=0;i<=3;i++) {

  setTimeout(function(){

    console.log(i)

  },10)

}

1、let 引入了块级作用域概念,创建setTimeout的时候,变量i只在作用域内生效。对于循环的每一次,引用的i都是不同的

for (let i=0;i<=3;i++) {

  (function(i){

    setTimeout(function(){

      console.log(i)

    },10)

  })(i)

}

2、变量提升问题

console.log(i)

var i = 1;

// let i = 1;  // 报错

3、const 常量

const i = 1;

// i=2 // 报错

#### 箭头函数

1、箭头函数的this是在什么位置定义决定的,普通函数的this是在使用的时候决定的

const obj = {

  name: "123",

  getName1: () => {

    return this.name // window.name

  },

  getName2: function() {

    return this.name // obj.name

  }

}

2、简写

const arrow = (value) => Number(value)

相当于

const arrow = function(value) {

  return Number(value)

}

const arrow = (value) => ({}) // 返回对象

3、箭头函数不能被用作构造函数

构造函数:改变this指向,指向新实例。

箭头函数:this是在定义的时候决定的。

#### class

class Test {

  _name = '';

  constructor(name) {

    this.name = name

  }

  static getF() {

    return `$(this.name)123123`

  }

  get name(val) {

    return `${this._name} - 加一层包装`;

  }

  set name() {

    console.log("检测到了name的赋值操作");

    this._name = val;

  }

}

const instance = new Test('ww') // 实例属性

console.log(instance.name)

console.log(Test.getF()) // 静态属性  

#### 模板字符串

const a = '111\n222'

const b = `111

222`

render函数实现template的功能

const year = "2022";

const month = "10";

const day = "01";

const template = '${year}-${month}-${day}'

const context = {year, month, day}

const str = render(template)(context)

console.log(str) // 2020-10-01

function render(template) {

  return function(context) {

    return template.replace(/\$\{(.*?)\}/g, (match, key) => context[key]);

  }

}

#### 解构

1、数组 // 找索引

let arr = [1,2,3]

let [a,b,c] = [1,2,3]

let [a,b,c] = [{

  name:'1'

},{

  name:'2'

}]

console.log(a.name,b.name)

2、对象 // 找值

const {a1, a2} = {a1:"123", a2: "456"}

console.log(a1, a2)

3、解构的原理

针对可迭代对象Iterator,通过遍历按照顺序获取对应的值进行赋值

3.1 Iterator 是什么

Iterator是一种接口,interface,为各种不一样的数据解构提供统一的访问机制

任何数据解构只要有Iterator接口

for of,相当于一个遍历器,遍历数据的时候,去寻找Iterator

const obj = {name: "123"}

for(n of obj){console.log(n)}  // 报错:VM146:2 Uncaught TypeError: obj is not iterable

对象里没有 iterable

3.2 Iterator 有什么用呢

###### 为各种不同的数据解构提供统一的访问接口

###### 数据解构按照顺序处理

###### for of 可以进行遍历

let nextIndex = 0;

function generateIterator(array) {

  return {

    next: () => nextIndex < array.length ? {

      value: array[next++],

      done: false

    } : {

      value: undefined,

      done: true

    }>

  }

}

const iterator = generateIterator([1,2,3])

console.log(iterator.next())

console.log(iterator.next())

value done

3.3 可迭代对象是什么

是Iterator接口的实现

可迭代对象存在两种协议,可迭代协议,迭代协议

  可迭代协议:对象必须实现iterator方法,对象或者原型链上必须有一个Symbol.iterator:()=>迭代器协议

  迭代器协议:必须实现一个next方法,next方法返回的对象done value

const obj = {

  count: 0,

  [Symbol.iterator]: () => {

    return {

      next: () => {

        obj.count++;

        if ( obj.count <= 10>) {

          return {

            value: obj.count,

            done:false

          }

        } else {

          return {

            value: undefined,

            done: true

          }

        }

      }

    }

  }

}

for (let item of obj) {

  console.log(item)

}

#### 遍历

1、for in

Object.prototype.moreName = 'ppppp';

let arr = [a,b,c]

let arr = {

  a: 1,

  b: 2

}

for (let item in arr) {

  console.log(item) // 数组输出索引;对象输出key

  if (item.hasOwnProperty) {

  }

}

不仅会遍历当前对象,还遍历原型链上的属性

不适合遍历数组

forEach 不会被break中断

2、for of

const arr = [

  {age: 12},

  {age: 22},

  {age: 32},

]

for (let {age} of arr) {

  if (age > 20) {

    break;

  }

  console.log(age)

}

#### Object

1 Object.keys 拿到的是key的数组

const obj = {

  a:1,b:2

}

console.log(Object.keys(obj))

function getObjectKeys(obj) {

  const result = [];

  for(const key in obj) {

    if (obj.hasOwnProperty(key)) {

      result.push(key);

    }

  }

  return result;

}

2 Object.values

const obj = {

  a:1,b:2

}

console.log(Object.values(obj))

function getObjectValues(obj) {

  const result = [];

  for(const key in obj) {

    if (obj.hasOwnProperty(key)) {

      result.push(obj[key]);

    }

  }

  return result;

}

3 Object.entries // 键值对的数组

const obj = {

  a:1,b:2

}

console.log(Object.values(obj))

function getObjectEntries(obj) {

  const result = [];

  for(const key in obj) {

    if (obj.hasOwnProperty(key)) {

      result.push([key, obj[key]]);

    }

  }

  return result;

}

4 Object.getOwnPropertyName // 获取对象自身的key,不包括原型

5 Object.getOwnPropertyDescriptor // 是对象属性的描述符,是一个对象

 configurable // false时,其他属性都不可改

 writable

 'use strict'

 enumerable // for in/Object.keys

 get set

 const obj = {};

let val = undefined;

Object.defineProperty(obj, 'a', {

  set: function (value) {

    console.log(`${value} - xxx `)

    val = value;

  },

  get: function () {

   

  },

  configurable: true

})

obj.a = 111;

console.log(obj.a)
 const obj = new Proxy({}, {

  get: function (target, propKey) {

    console.log(`invoke getter ${propKey}`)

    return target[propKey]

  },

  set: function (target, propKey, value) {

    console.log(`invoke setter ${propKey} ${value}`)

    return Reflect.set(target, propKey, value);

  }

})

obj.s = 1;

console.log(obj.s)

  Reflect 是什么?

  语言的优化,内部方法移动到Reflect上

  命令式的行为变成函数式的

  const obj = {name:1}

  delete obj.name // 命令

  Reflect.deleteProperty(obj, name) 函数

6 Object.assign // 浅拷贝 {...a, ...b}

const newObj = obj.assign({}, {

  name: '11',

  age: '22'

}, {

  name: '333' // 后面覆盖前面

})

console.log(newObj)



function shallowClone(source) {

  const target = {};

  for (const i in source) {

    if (source.hasOwnProperty[i]) {

      target[i] = source[i];

    }

  }

  return target;

}

Promise Promise.allSettled // 返回所有promise的状态和结果

function PromiseAllSettled(promiseArray) {

  return new Promise((resolve, reject) => {

    if (!Array.isArray(promiseArray)) {

      return reject(new TypeError('参数必须是一个数组'))

    }

    let counter = 0;

    const promiseNum = promiseArray.length;

    const resolvedArray = [];

    for (let i = 0; i < promiseNum; i++) {

      Promise.resolve(promiseArray[i]).then(value => {

        resolvedArray[i] = {

          status: 'fulfilled',

          value

        }

      })

        .catch(reason => {

          resolvedArray[i] = {

            status: 'rejected',

            reason

          }

        })

        .finally(() => {

          counter++;

          if (counter == promiseNum) {

            resolve(resolvedArray)

        }

      })

    }

  })

}

#### 数组

1. Array.flat(arr, deep)

const arr1 = [1, 2, [3, 4, [5]]];

console.log(arr1.flat(1))

console.log(arr1.flat(Infinity))
function flatDeep(arr, d = 1) {

  if (d > 0) {

    return arr.reduce((res, val) => {

      if (Array.isArray(val)) {

        res = res.concat(flatDeep(val,d - 1))

      } else {

        res = res.concat(val);

      }

      return res;

    }, [])

  } else {

    return arr.slice();

  }

}

flatDeep(arr1, Infinity)

2. Array.includes

const arr = [1,2,3]

console.log(arr.includes(2))

3. Array.from // 如何把一个类数组转换成真数组。

console.log(Array.from([1, 2, 3], x => x + 1))

// 如何把arguments转换成真数组。

1 [...arguments]

2 Array.from(arguments)

3 Array.prototype.slice.call(arguments)

# babel编译工具链的使用

//astexplorer.net 查看AST

1、解析

接受代码输出AST

*词法分析

*语法分析

2、转换

接受AST对其进行遍历,可以对节点进行添加 更新 移除等操作

3、生成

把转换过的AST生成为字符串形式的代码,并且创建source map

plugins.js

const template = require('babel-template')
const temp = template('var b=1');

module.exports = function ({
  types: t
}) {
  return {
    visitor: {
      VariableDeclaration(path, state) { // 变量声明
        // 找到AST节点
        const node = path.node;
        if (t.isVariableDeclaration(node, {
          kind: 'const'
        })) {
          node.kind = 'let';
          const inserNode = temp();
          path.inserBefore(inserNode);
        }
      }
    }
  }
}

babel.js

const myPlugin = require("./plugin");
const babel = require('@babel/core');
const constent = 'const name = 123';
const { code } = babel.transform(content, {
  plugins: [myPlugin]
})
console.log(code)

 类似资料: