关于前端:即将发布的-ES2021ES12中有哪些有趣的功能

46次阅读

共计 5825 个字符,预计需要花费 15 分钟才能阅读完成。

简述

ES2021(ES12)将于 2021 年中公布。在本文中,你将将会理解五个最乏味的性能:String.prototype.replaceAll(),数字分隔符,逻辑赋值运算符,Promise.any()WeakRef 和 Finalizers。

本文所形容的五个性能目前都处于第 4 阶段。这意味着它们曾经实现,并将要在 JavaScript 引擎中实现了。这意味着你不会浪费时间去学习一些可能永远也不会呈现的货色。

这些性能不久将会公布。如果有趣味,能够到官网 Ecma TC39 GitHub 去理解无关其余提案的更多信息。这个 Github 库跟踪了所有提案以及其以后所处的阶段。

String.prototype.replaceAll()

先从一个小性能 replaceAll() 开始,这是对 JavaScript 语言的一个补充。当你要替换字符串中屡次呈现的匹配模式时,目前能够用 replace() 办法,但问题是它只能替换第一次呈现的那个。

这并不意味着 replace() 不能替换所有呈现的匹配模式,只不过你必须用正则表达式才行。如果你能够承受那就没事儿了。不过对于很多 js 程序员来说,正则表达式并不是他们的菜(实际上是懒得学!)。

如果你就是这样的 js 程序员,必定喜爱新的 replaceAll() 办法。它的工作形式与 replace() 相似,区别在于 replaceAll() 能够不必正则表达式就能替换所有呈现的模式。

replaceAll() 也能承受正则表达式,你齐全能够用它代替 replace()

// 申明一个字符串
let str = 'There are those who like cats, there those who like watching cats and there are those who have cats.'

// 用 dogs 替换所有的“cats”:str = str.replaceAll('cats', 'dogs')
console.log(str)
// Output:
// 'There are those who like dogs, there those who like watching dogs and there are those who have dogs.'

// 用 replace() 的写法:str = str.replace(/cats/g, 'dogs')
console.log(str)
// Output:
// 'There are those who like dogs, there those who like watching dogs and there are those have dogs.'

数字分隔符

这是 JavaScript ES2021 的一个十分小的性能,能够让你在解决大量数字时更好过一点。数字分隔符提供了一种能使大数字更易于浏览和应用的简略办法。语法也很简略:一个下划线 _

// 不带数字分隔符的 Number 
const num = 3685134689

// 带数字分隔符的 Number 
const num = 3_685_134_689

不过数字分隔符只是在视觉上提供一些帮忙。在应用时不会对数值自身产生任何影响。

// 带数字分隔符的 Number 
const num = 3_685_134_689

// 输入:
console.log(num)
// Output:
// 3685134689

逻辑赋值运算符

JavaScript 容许在布尔上下文中应用逻辑运算符。例如在 if ... else语句和 三目运算符 中检测是 true 还是 false。ES2021 的逻辑赋值运算符将逻辑运算符与赋值表达式(=)组合在了一起。

在 JavaScript 中曾经有了一些 赋值运算符,例如:加法赋值(+=),减法赋值(-=),乘法赋值(*=)等。在 ES2021 中又减少了对逻辑运算符 &&||??([空值合并)的反对。

//////////////////
// 逻辑与赋值运算符 (&&=)
//////////////////
x &&= y

// 以上代码相当于:
x = x && d
// 或者:
if (x) {x = y}

// 例 1:
let x = 3 
let y = 0 
x &&= y
console.log(x)
// Output:
// 0

// 例 2:
let x = 0 
let y = 9 
x &&= y
console.log(x)
// Output:
// 0

// 例 3:
let x = 3 // Truthy value.
let y = 15 // Truthy value.
x &&= y
console.log(x)
// Output:
// 15


//////////////////
// 逻辑或赋值运算符 (||=):
x ||= y

// 相当于:
x = x || y
// 或者:
if (!x) {x = y}

// 例 1:
let x = 3
let y = 0
x ||= y

console.log(x)
// Output:
// 3

// 例 2:
let x = 0 
let y = 9 
x ||= y

console.log(x)
// Output:
// 9

// 例 3:
let x = 3 
let y = 15
x ||= y

console.log(x)
// Output:
// 3


/////////////////////////
// 空值合并赋值运算符 (??=):
/////////////////////////
x ??= y

// 相当于:
x = x ?? y
// 或者:
if (x == null || x == undefined) {x = y}

// 例 1:
let x = null 
let y = 'Hello' 
x ??= y
console.log(x)
// Output:
// 'Hello'

// 例 2:
let x = 'Jay' 
let y = 'Hello' 
x ??= y
console.log(x)
// Output:
// 'Jay'

// 例 3:
let x = 'Jay'
let y = null 
x ??= y
console.log(x)
// Output:
// 'Jay'

// 例 4:
let x = undefined 
let y = 'Jock' 
x ??= y

console.log(x)
// Output:
// 'Jock'

看一下下面的例子。首先是 x && = y。仅当 x 为真时,才将 y 赋值给 x。其次是 x || = y,仅当 x 为假时,才将 y 赋值给 x。如果 x 是真,而 y 是假,则不会进行赋值。

如果 xy 都是假,也会产生同样的状况。最初是 x ?? = y。仅当 xnullundefined 时,才将 y 调配给 x。如果 x 既不是 null 也不是 undefined 则不会进行赋值,如果 ynullundefined 也一样。

Promise.any()

在 ES6 中引入了 Promise.race()Promise.all() 办法,ES2020 退出了 Promise.allSettled()。ES2021 又减少了一个使 Promise 解决更加容易的办法:Promise.any()

Promise.any() 办法承受多个 promise,并在实现其中任何一个的状况下返回 promise。其返回的是 Promise.any() 实现的第一个 promise。如果所有 promise 均被回绝,则 Promise.any() 将返回 AggregateError,其中蕴含回绝的起因。

// 例 1: 全副被实现:
// 创立 promises:
const promise1 = new Promise((resolve, reject) => {setTimeout(() => {resolve('promise1 is resolved.')
  }, Math.floor(Math.random() * 1000))
})

const promise2 = new Promise((resolve, reject) => {setTimeout(() => {resolve('promise2 is resolved.')
  }, Math.floor(Math.random() * 1000))
})

const promise3 = new Promise((resolve, reject) => {setTimeout(() => {resolve('promise3 is resolved.')
  }, Math.floor(Math.random() * 1000))
})

;(async function() {// Await the result of Promise.any():
  const result = await Promise.any([promise1, promise2, promise3])
  console.log(result)
  // Output:
  // 'promise1 is resolved.', 'promise2 is resolved.' or 'promise3 is resolved.'
})()


// 例 2: 局部实现:
const promise1 = new Promise((resolve, reject) => {setTimeout(() => {resolve('promise1 is resolved.')
  }, Math.floor(Math.random() * 1000))
})

const promise2 = new Promise((resolve, reject) => {setTimeout(() => {reject('promise2 was rejected.')
  }, Math.floor(Math.random() * 1000))
})

;(async function() {// Await the result of Promise.any():
  const result = await Promise.any([promise1, promise2])
  console.log(result)
  // Output:
  // 'promise1 is resolved.'
})()


// 例 3: 均被回绝:
const promise1 = new Promise((resolve, reject) => {setTimeout(() => {reject('promise1 was rejected.')
  }, Math.floor(Math.random() * 1000))
})

const promise2 = new Promise((resolve, reject) => {setTimeout(() => {reject('promise2 was rejected.')
  }, Math.floor(Math.random() * 1000))
})

;(async function() {
  // Use try...catch to catch the AggregateError:
  try {// Await the result of Promise.any():
    const result = await Promise.any([promise1, promise2])
  }

  catch (err) {console.log(err.errors)
    // Output:
    // ['promise1 was rejected.', 'promise2 was rejected.']
  }
})()

弱援用:WeakRef

最初一个抢眼的性能是 WeakRefs。在 JavaScript 中,当你创立了一个创建对象的援用时,这个援用能够避免对象被 gc 回收,也就是说 JavaScript 无奈删除对象并开释其内存。只有对该对象的援用始终存在,就能够使这个对象永远存在。

ES2021 了新的类 WeakRefs。容许创建对象的弱援用。这样就可能在跟踪现有对象时不会阻止对其进行垃圾回收。对于缓存和对象映射十分有用。

必须用 new关键字创立新的 WeakRef,并把某些对象作为参数放入括号中。当你想读取援用(被援用的对象)时,能够通过在弱援用上调用 deref() 来实现。上面是一个非常简单的例子。

const myWeakRef = new WeakRef({
  name: 'Cache',
  size: 'unlimited'
})

console.log(myWeakRef.deref())
// Output:
// {name: 'Cache', size: 'unlimited'}

console.log(myWeakRef.deref().name)
// Output:
// 'Cache'

console.log(myWeakRef.deref().size)
// Output:
// 'unlimited'

Finalizers 和 FinalizationRegistry

WeakRef 严密相连的还有另一个性能,名为 finalizers 或 FinalizationRegistry。这个性能容许你注册一个回调函数,这个回调函数将会在对象被 gc 回收时调用。。

// 创立 FinalizationRegistry:
const reg = new FinalizationRegistry((val) => {console.log(val)
})

;(() => {
  // 创立新对象:
  const obj = {}

  // 为“obj”对象注册 finalizer:// 第一个参数:要为其注册 finalizer 的对象。// 第二个参数:下面定义的回调函数的值。reg.register(obj, 'obj has been garbage-collected.')
})()
// 当 "obj" 被 gc 回收时输入:// 'obj has been garbage-collected.'

官网倡议不要轻易应用 WeakRef 和 finalizer。其中一个起因是它们可能不可预测,另一个是它们并没有真正帮 gc 实现工作,实际上可能会 gc 的工作更加艰难。你能够在它的提案中具体理解其起因。

总结

与以前的 JavaScript 标准(例如 ES6 和 ES2020)相比,看上去 ES2021 的更新不多。然而这些乏味的性能值得咱们关注。


本文首发微信公众号:前端先锋

欢送扫描二维码关注公众号,每天都给你推送陈腐的前端技术文章


欢送持续浏览本专栏其它高赞文章:

  • 深刻了解 Shadow DOM v1
  • 一步步教你用 WebVR 实现虚拟现实游戏
  • 13 个帮你进步开发效率的古代 CSS 框架
  • 疾速上手 BootstrapVue
  • JavaScript 引擎是如何工作的?从调用栈到 Promise 你须要晓得的所有
  • WebSocket 实战:在 Node 和 React 之间进行实时通信
  • 对于 Git 的 20 个面试题
  • 深刻解析 Node.js 的 console.log
  • Node.js 到底是什么?
  • 30 分钟用 Node.js 构建一个 API 服务器
  • Javascript 的对象拷贝
  • 程序员 30 岁前月薪达不到 30K,该何去何从
  • 14 个最好的 JavaScript 数据可视化库
  • 8 个给前端的顶级 VS Code 扩大插件
  • Node.js 多线程齐全指南
  • 把 HTML 转成 PDF 的 4 个计划及实现

  • 更多文章 …

正文完
 0