es2017到es2022新特性

317 阅读4分钟

es2017

  1. Object.values
  2. Object.entries()
  3. Object.getOwnPropertyDescriptors()返回一个对象的所有自身属性的描述符(.value,.writable,.get,.set,.configurable,enumerable)
  4. padStart()和padEnd()

es2018

  1. async/await
  2. Promise.finally
  3. rest/扩展运算符支持了对象
    const object = {
      a: 1,
      b: 2,
      c: 3,
      d: 4,
      e: 5
    };
    const { a,b, ...rest } = object;
    // a = 1
    // b = 2
    // rest = { c: 3, d: 4, e: 5 }
    

es2019

  1. Object.fromEntries 和 Object.entries相反
  2. Array.prototype.flat,其接受一个可选参数表示需要展开的深度,默认值为1,可以帮助我们快速实现数组降维
    const arr1 = [0, 1, 2, [3, 4]];
    console.log(arr1.flat());
    // expected output: [0, 1, 2, 3, 4]
    
    const arr2 = [0, 1, 2, [[[3, 4]]]];
    console.log(arr2.flat(2));
    // expected output: [0, 1, 2, [3, 4]]
    
  3. flatMap()方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为 1 的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些。
    const arr1 = [1, 2, [3], [4, 5], 6, []];
    
    const flattened = arr1.flatMap(num => num);
    
    console.log(flattened);
    // expected output: Array [1, 2, 3, 4, 5, 6]
    
  4. String.trimStart 和 String.trimEnd
    • 等价于之前的String.trimRight 和 String.trimLeft
  5. Function.toString() 更新
    • 之前的版本中,Function.toString()直接把空格去掉
    • 但是,在ES2019中,会完全保留源码格式打印

es2020

  1. 可选链操作符(Optional Chaining
    let nestedProp = obj?.first?.second;
    
    • 如果obj或obj.first是null/undefined,表达式将会短路计算直接返回undefined
  2. 空位合并操作符(Nullish coalescing Operator
    let x = {
      profile: {
        name: '浪里行舟',
        age: ''
      }
    }
    console.log(x.profile.age || 18) //18
    
    • 上例中age的属性为空字符串,却被等同为假值,为了解决这个问题
    let c = a ?? b;
    // 等价于let c = a !== undefined && a !== null ? a : b;
    
  3. Promise.allSettled
    • Promise.allSettled跟Promise.all类似, 其参数接受一个Promise的数组, 返回一个新的Promise, 唯一的不同在于, 它不会进行短路, 也就是说当Promise全部处理完成后,我们可以拿到每个Promise的状态, 而不管是否处理成功
    Promise.allSettled([
      Promise.reject({ code: 500, msg: '服务异常' }),
      Promise.resolve({ code: 200, list: [] }),
      Promise.resolve({ code: 200, list: [] })
    ]).then(res => {
      console.log(res)
      /*
            0: {status: "rejected", reason: {}}
            1: {status: "fulfilled", value: {}}
            2: {status: "fulfilled", value: {}}
        */
      // 过滤掉 rejected 状态,尽可能多的保证页面区域数据渲染
      RenderContent(
        res.filter(el => {
          return el.status !== 'rejected'
        })
      )
    })
    
  4. String.prototype.matchAll
    const regexp = /t(e)(st(\d?))/g;
    const str = 'test1test2';
    
    const array = [...str.matchAll(regexp)];
    
    console.log(array[0]);
    // expected output: Array ["test1", "e", "st1", "1"]
    
    console.log(array[1]);
    // expected output: Array ["test2", "e", "st2", "2"]
    
  5. Dynamic import
    el.onclick = () => {
      import('/modules/my-module.js')
        .then(module => {
          // Do something with the module.
        })
        .catch(err => {
          // load error;
        })
    }
    //另外一种
    let module = await import('/modules/my-module.js');
    
  6. BigInt
    • 它是第7个原始类型,可安全地进行大数整型计算
    • 创建 BigInt 类型的值也非常简单,只需要在数字后面加上 n 即可。例如,123 变为 123n
  7. globalThis
    • globalThis 是一个全新的标准方法用来获取全局 this
    • 如果您在浏览器上,globalThis将为window,如果您在Node上,globalThis则将为global。因此,不再需要考虑不同的环境问题
    // ES2020内置
    globalThis.Array(0,1,2) // [0,1,2]
    
    // 定义一个全局对象v = { value:true } ,ES2020用如下方式定义
    globalThis.v = { value:true }
    
    

es2021

  1. 数字分割符
1000000000000   1019436871.42
1_000_000_000_000    1_019_436_871.42
  1. Promise.any
    • 接收一个由Promise所组成的可迭代对象,该方法会返回一个新的promise,一旦可迭代对象内的任意一个 promise变成了兑现状态,那么由该方法所返回的 promise就会变成兑现状态,并且它的兑现值就是可迭代对象内的首先兑现的promise的兑现值
    • 如果可迭代对象内的promise最终都没有兑现(即所有 promise都被拒绝了),那么该方法所返回的 promise 就会变成拒绝状态
    • 并且它的拒因会是一个AggregateError实例,这是Error的子类,用于把单一的错误集合在一起
  2. String.prototype.replaceAll()
'aabbcc'.replaceAll('b', '.') // 'aa..cc'
  1. &&=,仅当左为真时,才将右变量值赋给左变量
let num1 = 5
let num2 = 10
num1 &&= num2
console.log(num1) // 10
  1. ||=,仅当左为假时,才将右变量赋给左变量
let num1
let num2 = 10
num1 ||= num2
console.log(num1) // 10
  1. ??=,空值合并运算符
let num1
let num2 = 10
num1 ??= num2
console.log(num1) // 10
num1 = false
num1 ??= num2
console.log(num1) // false

es2022

  1. at()获取索引值
const a = [1,2,3]
a.at(1) // 2
a.at(-1) // 3
  1. 错误包装
try {
  return await fetch('//unintelligible-url-a') // 抛出一个 low level 错误
    .catch(err => {
      throw new Error('Download raw resource failed', { cause: err }) // 将 low level 错误包装成一个 high level、易懂的错误
    })
} catch (err) {
  console.log(err)
  console.log('Caused by', err.cause)
  // Error: Download raw resource failed
  // Caused by TypeError: Failed to fetch
}
  1. 顶层await,顶层 await 能在模块 modules 的顶层正常工作。(在 class 代码块或非 async 函数仍不支持。)
const serviceName = await fetch("https://example.com/what-service-should-i-use")
const service = await import(`/services/${serviceName}.js`)

const params = new URLSearchParams(location.search);
const theme = params.get('theme');
const stylingFunctions = await import(`/styling-functions-${theme}.js`);

// 支持条件导入
const date = new Date()
if(date.getFullYear() === 2023) {
  await require('/special-code-for-2023-year.js')
}
  1. 类的私有属性和方法
class Human {
  #name = "John";
  
  setName(name) {
    this.#name = name;
  }
}

const human = new Human()
human.#name = 'Amy'  // ERROR!
human.setName('Amy') // OK
class Human {
  name = "John";
  
  constructor(name) {
    this.#setName('Amy') // OK
  }
  
  #setName(name) {
    this.name = name;
  }
}

const human = new Human()
human.#setName('Amy') // ERROR!