ECMAScript2020~2021全特性学习宝典

前言

文章字数限制 ES6~ES10 参考 ECMAScript2016~2019全特性学习宝典html

ECMAScript2020(ES11)

String 扩展

  • String.prototype.matchAll()

matchAll() 方法返回一个包含全部匹配正则表达式及分组捕获结果的迭代器前端

const str = ` <html> <body> <div>第一个div</div> <p>这是一个p</p> <span>span</span> <div>第二个div</div> <body> </html> `
复制代码

请找出全部的div元素。node

function selectDiv(regExp, str) {
    let matches = []
    for (let match of str.matchAll(regExp)) {
        matches.push(match[1])
    }
    return matches
}
const res = selectDiv(regExp, str)
console.log(res)
复制代码

Dynamic Import

按需 import 提案几年前就已提出,现在终于能进入ES正式规范。这里我的理解成“按需”更为贴切。现代前端打包资源愈来愈大,打包成几M的JS资源已成常态,而每每前端应用初始化时根本不须要全量加载逻辑资源,为了首屏渲染速度更快,不少时候都是按需加载,好比懒加载图片等。而这些按需执行逻辑资源都体如今某一个事件回调中去加载。webpack

页面上有一个按钮,点击按钮才去加载ajax模块。web

const oBtn = document.querySelector('#btn')
oBtn.addEventListener('click', () => {
    import('./ajax').then(mod => {
        // console.log(mod)
        mod.default('static/a.json', res => {
            console.log(res)
        })
    })
})
复制代码

固然,webpack目前已很好的支持了该特性。ajax

BigInt

在 ES10 增长了新的原始数据类型:BigInt,表示一个任意精度的整数,能够表示超长数据,能够超出2的53次方。正则表达式

Js 中 Number类型只能安全的表示-(2^53-1)至 2^53-1 范的值json

console.log(2 ** 53) // es7 幂运算符
console.log(Number.MAX_SAFE_INTEGER) // 最大值-1
复制代码

使用 BigInt 有两种方式:segmentfault

  • 方式一:数字后面增长n
const bigInt = 9007199254740993n
console.log(bigInt)
console.log(typeof bigInt) // bigint

console.log(1n == 1) // true
console.log(1n === 1) // false
复制代码
  • 方式二:使用 BigInt 函数
const bigIntNum = BigInt(9007199254740993n)
console.log(bigIntNum)
复制代码

Promise.allSettled()

学习了ES新特性,咱们都知道 Promise.all() 具备并发执行异步任务的能力。但它的最大问题就是若是其中某个任务出现异常(reject),全部任务都会挂掉,Promise直接进入reject 状态。而 Promise.allSettled 返回一个在全部给定的promise已被决议或被拒绝后决议的promise,并带有一个对象数组,每一个对象表示对应的promise结果。数组

Promise.allSettled([
    Promise.reject({
        code: 500,
        msg: '服务异常'
    }),
    Promise.resolve({
        code: 200,
        data: ['1', '2', '3']
    }),
    Promise.resolve({
        code: 200,
        data: ['4', '5', '6']
    })
]).then(res => {
    console.log(res)
    // console.log('成功')
    const data = res.filter(item => item.status === 'fulfilled')
    console.log(data)
}).catch(err => {
    console.log(err)
    console.log('失败')
})
复制代码

globalThis

Javascript 在不一样的环境获取全局对象有不通的方式:

  • node 中经过 global
  • web 中经过 window, self 等.

self:打开任何一个网页,浏览器会首先建立一个窗口,这个窗口就是一个window对象,也是js运行所依附的全局环境对象和全局做用域对象。self 指窗口自己,它返回的对象跟window对象是如出一辙的。也正由于如此,window对象的经常使用方法和函数均可以用self代替window。

globalThis 提供了一个标准的方式来获取不一样环境下的全局 this 对象(也就是全局对象自身)。不像 window 或者 self 这些属性,它确保能够在有无窗口的各类环境下正常工做。因此,你能够安心的使用 globalThis,没必要担忧它的运行环境。为便于记忆,你只须要记住,全局做用域中的 this 就是 globalThis。

console.log(globalThis)
复制代码

可选链 Optional chaining

可以让咱们在查询具备多层级的对象时,再也不须要进行冗余的各类前置校验。

const user = {
    address: {
        street: 'xx街道',
        getNum() {
            return '80号'
        }
    }
}
复制代码

在以前的语法中,想获取到深层属性或方法,不得不作的前置校验,不然很容易命中 Uncaught TypeError: Cannot read property... 这种错误,这极有可能让你整个应用挂掉。

const street = user && user.address && user.address.street
const num = user && user.address && user.address.getNum && user.address.getNum()
console.log(street, num)
复制代码

用了 Optional Chaining ,上面代码会变成

const street2 = user?.address?.street
const num2 = user?.address?.getNum?.()
console.log(street2, num2)
复制代码

可选链中的 ? 表示若是问号左边表达式有值, 就会继续查询问号后面的字段。根据上面能够看出,用可选链能够大量简化相似繁琐的前置校验操做,并且更安全。

空值合并运算符(Nullish coalescing Operator)

空值合并运算符(??)是一个逻辑运算符。当左侧操做数为 null 或 undefined 时,其返回右侧的操做数。不然返回左侧的操做数。

当咱们查询某个属性时,常常会遇到,若是没有该属性就会设置一个默认的值。

const b = 0 // 或者null undefined false
const a = b || 5
console.log(a)
复制代码

空值合并运算符 ?? 咱们仅在第一项为 null 或 undefined 时设置默认值

// false 0 无效
const a = b ?? 123
console.log(a)
复制代码

ECMAScript2021(ES12)

replaceAll

返回一个全新的字符串,全部符合匹配规则的字符都将被替换掉

const str = 'hello world';
str.replaceAll('l', ''); // "heo word"
复制代码

Promise.any

Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。若是可迭代对象中没有一个 promise 成功(即全部的 promises 都失败/拒绝),就返回一个失败的 promise。

const promise1 = new Promise((resolve, reject) => reject('我是失败的Promise_1'));
const promise2 = new Promise((resolve, reject) => reject('我是失败的Promise_2'));
const promiseList = [promise1, promise2];
Promise.any(promiseList)
.then(values=>{
  console.log(values);
})
.catch(e=>{
  console.log(e);
});
复制代码

WeakRefs

WeakRefs的Class类建立对对象的弱引用(对对象的弱引用是指当该对象应该被GC回收时不会阻止GC的回收行为)

当咱们经过(const、let、var)建立一个变量时,垃圾收集器GC将永远不会从内存中删除该变量,只要它的引用仍然存在可访问。WeakRef对象包含对对象的弱引用。对对象的弱引用是不会阻止垃圾收集器GC恢复该对象的引用,则GC能够在任什么时候候删除它。

WeakRefs在不少状况下都颇有用,好比使用Map对象来实现具备不少须要大量内存的键值缓存,在这种状况下最方便的就是尽快释放键值对占用的内存。

目前,能够经过WeakMap()或者WeakSet()来使用WeakRefs

我想要跟踪特定的对象调用某一特定方法的次数,超过1000条则作对应提示

let map = new Map()
function doSomething(obj){
	...
}
function useObject(obj){
	doSomething(obj)
  
  let called = map.get(obj) || 0
  called ++ 
  
  if(called>1000){
     console.log('当前调用次数已经超过1000次了,over')
  }
  
  map.set(obj, called)
}
复制代码

如上虽然能够实现咱们的功能,可是会发生内存溢出,由于传递给doSomething函数的每一个对象都永久保存在map中,而且不会被GC回收,所以咱们可使用WeakMap

let wmap = new WeakMap()
function doSomething(obj){
	...
}
function useObject(obj){
	doSomething(obj)
  
  let called = wmap.get(obj) || 0
  
  called ++
  
  if(called>1000){
     console.log('当前调用次数已经超过1000次了,over')
  }
  
  wmap.set(obj, called)
}
复制代码

逻辑运算符和赋值表达式

运算符和赋值表达式,新特性结合了逻辑运算符(&&,||,??)和赋值表达式而JavaScript已存在的 复合赋值运算符有以下

a ||= b
//等价于
a = a || (a = b)

a &&= b
//等价于
a = a && (a = b)

a ??= b
//等价于
a = a ?? (a = b)
复制代码

数字分隔符

数字分隔符,能够在数字之间建立可视化分隔符,经过_下划线来分割数字,使数字更具可读性

const money = 1_000_000_000;
//等价于
const money = 1000000000;

1_000_000_000 === 1000000000; // true
复制代码

参考文章

相关文章
相关标签/搜索