乐趣区

关于javascript:JavaScript-ES2021-最值得期待的-5-个新特性解析

在写本文时,本文提到的新的 JavaScript 提案性能已进入第 4 阶段,并且简直必定会蕴含在 ES2021 中。你曾经能够开始在 最新版本的浏览器,Node.js 和 Babel 中应用。

留神:ECMAScript 是 JavaScript 所基于的规范,由 TC39 委员会治理。ECMAScript 始终是一个不须要的名称,这会使所有都对初学者感到困惑。人们常常议论 JavaScript 性能,但参考的是 ECMAScript 标准。

更新个性

  • 数字分隔符(_
  • 逻辑调配(&&=||=??=
  • 援用有余(WeakRefFinalizationRegistry
  • Promise.any
  • String.prototype.replaceAll

1. 数值分隔符

大数字文字很难使人眼疾速解析,尤其是当有很多反复的数字时:

1000000000000   1019436871.42

为了进步可读性,新的 JavaScript 语言性能 启用了下划线作为数字文字中的分隔符。因而,下面的内容当初能够重写为每千位数字,例如:

1_000_000_000_000    1_019_436_871.42

当初,更容易说出第一个数字是 1 万亿,而第二个数字大概是 10 亿。

数字分隔符有助于进步各种数字文字的可读性:

// A decimal integer literal with its digits grouped per thousand:
1_000_000_000_000
// A decimal literal with its digits grouped per thousand:
1_000_000.220_720
// A binary integer literal with its bits grouped per octet:
0b01010110_00111000
// A binary integer literal with its bits grouped per nibble:
0b0101_0110_0011_1000
// A hexadecimal integer literal with its digits grouped by byte:
0x40_76_38_6A_73
// A BigInt literal with its digits grouped per thousand:
4_642_473_943_484_686_707n

它们甚至实用于八进制整数文字(只管 我想不出 其中分隔符为此类文字提供值 的示例):

// A numeric separator in an octal integer literal: 🤷♀️
0o123_456

请留神,JavaScript 还具备不带显式 0o 前缀的八进制文字的新式语法。例如,017 === 0o17。在严格模式下或模块内不反对此语法,并且在古代代码中不应应用此语法。因而,这些文字不反对数字分隔符。应用 0o17 格调的文字代替。

2. Promise combinators

自从 ES2015 中引入 Promise 以来,JavaScript 齐全反对两种 Promise 组合器:静态方法 Promise.all 和 Promise.race。

目前有两个新提案正在通过标准化流程:Promise.allSettled 和 Promise.any。有了这些增加,JavaScript 中将总共有四个诺言组合器,每个组合器反对不同的用例。

以下是这四个组合器的概述:

2.1 Promise.allSettled

Promise.allSettled 给你当所有输出的诺言是一种信号结算,这意味着他们要么履行或回绝。如果您不在乎承诺的状态,而只是想晓得工作何时实现,无论它是否胜利,这都是很有用的。

例如,您能够启动一系列独立的 API 调用,并应用 Promise.allSettled 它们来确保它们已全副实现,而后再执行其余操作,例如删除加载微调器:

const promises = [fetch('/api-call-1'),
  fetch('/api-call-2'),
  fetch('/api-call-3'),
];
// Imagine some of these requests fail, and some succeed.

await Promise.allSettled(promises);
// All API calls have finished (either failed or succeeded).
removeLoadingIndicator();

2.2 Promise.any

Promise.any 办法和 Promise.race 相似——只有给定的迭代中的一个 promise 胜利,就采纳第一个 promise 的值作为它的返回值,但与 Promise.race 的不同之处在于——它会等到所有 promise 都失败之后,才返回失败的值:

const promises = [fetch('/endpoint-a').then(() => 'a'),
  fetch('/endpoint-b').then(() => 'b'),
  fetch('/endpoint-c').then(() => 'c'),
];
try {const first = await Promise.any(promises);
  // Any of the promises was fulfilled.
  console.log(first);
  // → e.g. 'b'
} catch (error) {
  // All of the promises were rejected.
  console.assert(error instanceof AggregateError);
  // Log the rejection values:
  console.log(error.errors);
  // → [
  //     <TypeError: Failed to fetch /endpoint-a>,
  //     <TypeError: Failed to fetch /endpoint-b>,
  //     <TypeError: Failed to fetch /endpoint-c>
  //   ]
}

此代码示例查看哪个端点响应最快,而后将其记录下来。只有当 所有 申请都失败时,咱们才最终进入代码 catch 块,而后在其中处理错误。

Promise.any 回绝能够一次代表多个谬误。为了在语言级别反对此性能,引入了一种新的谬误类型,称为 AggregateError。除了下面示例中的根本用法外,还能够以编程形式结构 AggregateError 对象,就像其余谬误类型一样:

const aggregateError = new AggregateError([errorA, errorB, errorC], 'Stuff went wrong!');

3. Weak references and finalizers

此性能蕴含两个高级对象 WeakRefFinalizationRegistry。依据应用状况,这些接口能够独自应用,也能够一起应用。正确应用它们须要认真思考,如果可能,最好防止应用它们。

一般来说,在 JavaScript 中,对象的援用是强保留的,这意味着只有持有对象的援用,它就不会被垃圾回收。

const ref = {x: 42, y: 51};
// 只有咱们拜访 ref 对象(或者任何其余援用指向该对象),这个对象就不会被垃圾回收

目前在 Javascript 中,WeakMap 和 WeakSet 是弱援用对象的惟一办法:将对象作为键增加到 WeakMap 或 WeakSet 中,是不会阻止它被垃圾回收的。

JavaScript 的 WeakMap 并不是真正意义上的弱援用:实际上,只有键依然存活,它就强援用其内容。WeakMap 仅在键被垃圾回收之后,才弱援用它的内容。

WeakRef 是一个更高级的 API,它提供了真正的弱援用,Weakref 实例具备一个办法 deref,该办法返回被援用的原始对象,如果原始对象已被收集,则返回 undefined 对象。

JavaScript 中对象的援用是强援用,WeakMap 和 WeakSet 能够提供局部的弱援用性能,若想在 JavaScript 中实现真正的弱援用,能够通过配合应用 WeakRef 和终结器(Finalizer)来实现。

WeakRef 是用来指指标对象不脱离垃圾收集保留它的对象。如果未通过垃圾回收回收指标对象,则 WeakRefs 能够勾销援用以容许拜访指标对象。

// Create a WeakRef object referring to a given target object
const ref = new WeakRef(targetObject)

// Return the WeakRef instance's target object, or undefined if the target object has been garbage-collected
const obj = ref.deref()

应用 FinalizationRegistry 对象能够在垃圾回收对象时申请回调。

// Create a registry object that uses the given callback
const registry = new FinalizationRegistry([callback])

// Register an object with a registry instance so that if the object is garbage-collected, the registry's callback may get called
registry.register(target, heldValue, [unregisterToken])

// Unregister a target object from a registry instance
registry.unregister(unregisterToken)

更多信息:TC39 提案,V8

4. String.prototype.replaceAll

以后,如果不应用全局正则表达式,就无奈替换字符串中子字符串的所有实例。与字符串参数一起应用时,String.prototype.replace 仅影响首次呈现。

String.prototype.replaceAll() 将为开发人员提供一种简略的办法来实现此常见的基本操作。

'aabbcc'.replaceAll('b', '.') // 'aa..cc'
'aabbcc'.replaceAll(/b/g, '.') // 'aa..cc'

5. Logical assignment (逻辑调配)

反对与新的经营逻辑调配 &&=||=??=。与它们的 数学和按位对应物不同,逻辑调配遵循其各自逻辑操作的短路行为。仅当逻辑运算将评估右侧时,它们才执行调配。

// falsy: false, 0, -0, 0n, "", null, undefined, and NaN
// truthy: all values are truthy unless defined as falsy
// nullish: null or undefined

a ||= b
// Logical OR assignment
// Equivalent to: a || (a = b);
// Only assigns if a is falsy

a &&= b
// Logical AND assignment
// Equivalent to: a && (a = b);
// Only assigns if a is truthy

a ??= b
// Logical nullish assignment
// Equivalent to: a ?? (a = b);
// Only assigns if a is nullish

5.1 具体例子

带有 && 运算符的逻辑赋值运算符

仅当 LHS 值为真时,才将 RHS 变量值赋给 LHS 变量。

// Logical Assignment Operator with && operator
let num1 = 5
let num2 = 10
num1 &&= num2
console.log(num1) // 10
// Line 5 can also be written as following ways
// 1. num1 && (num1 = num2)
// 2. if (num1) num1 = num2

带有 || 的运算符逻辑赋值运算符

仅当 LHS 值为假时,才将 RHS 变量值赋给 LHS 变量。

// Logical Assignment Operator with || operator
let num1
let num2 = 10
num1 ||= num2
console.log(num1) // 10
// Line 5 can also be written as following ways
// 1. num1 || (num1 = num2)
// 2. if (!num1) num1 = num2

带有 ?? 运算符的逻辑赋值运算符

ES2020 引入了空值合并运算符,其也能够与赋值运算符联合应用。
仅当 LHS 为 undefined 或仅为 null 时,才将 RHS 变量值赋给 LHS 变量。

// Logical Assignment Operator with ?? operator
let num1
let num2 = 10
num1 ??= num2
console.log(num1) // 10
num1 = false
num1 ??= num2
console.log(num1) // false
// Line 5 can also be written as following ways
// num1 ?? (num1 = num2)

概括

作为开发人员,跟紧语言的新个性是很重要的。

以上将在 2021 年公布的一些新性能,它们是进入第 4 阶段的提案,简直能够必定会包含在内,这些性能曾经在最新的浏览器和 babel 中实现。

欢送关注公众号:“全栈修炼 ”,回复“ 电子书”即能够取得 160 本前端精髓书籍哦。

参考文章:JavaScript Features in 2021

往期精文

  • Vue3 全家桶 + Element Plus + Vite + TypeScript + Eslint 我的项目配置最佳实际
  • TypeScript 中晋升幸福感的 10 个高级技巧
  • 举荐 7 个 Vue2、Vue3 源码解密剖析的重磅开源我的项目

通过浏览本篇文章,如果有播种的话,能够 点个赞 在看,这将会成为我继续分享的能源,感激~

退出移动版