2021 年 6 月 22 日,第 121 届 Ecma 国际(Ecma International)大会以远程会议形式召开。正式通过了ES2021标准,ECMAScript 2021 (ES12)成为事实的 ECMAScript 标准。
下面就直接说一下新的语法特性
逻辑空赋值运算符
字面字面意思, 当前面的值为逻辑空时 给它赋值 。所以首先这是一个赋值运算符,然后在赋值之前会做一个逻辑空的判断(=== null || === undefined)再决定要不要赋值。例子就直接搬mdn了
const a = { duration: 50 };
a.duration ??= 10;
console.log(a.duration);
// expected output: 50
a.speed ??= 25;
console.log(a.speed);
// expected output: 25
数字分割符
允许在数字(也就是number类型字面量)中间插入_下划线作为分割符 。
不能在两头 也不能连续下划线 .如下图
Promise.any
Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise 和AggregateError类型的实例,
AggregateError是 Error 的一个子类,用于把单一的错误集合在一起, 有一个 error 属性,属性值是由所有失败值填充的数组。本质上,这个方法和Promise.all()是相反的。
它和promise.race() 的区别就是只看结果,返回最先成功的那个, race是返回最先落定的那个期约, 无论成败。
Promise.all() 如果失败会立即返回失败的原因,而不是AggregateError对象。
String.prototype.repalceAll
就是字符串方法replace的全局版 ,等于传了一个有g关键字的正则。replaceAll()同样接受正则和字符串,但是当使用一个 regex时,您必须设置全局(“ g”)标志,
否则,它将引发 TypeError:“必须使用全局模式的 RegExp 调用 replaceAll”。
返回值是新的字符串。
WeakRef
弱引用 看到这个是不是自然就想起WeakMap 。 WeakRef 可以创建一个弱引用,但是尽量避免,除非你真的知道为什么要用它。那么什么叫强引用 ,什么叫弱引用。
弱引用是指该对象应该被CG回收时不会阻止CG的回收行为。 而与此相反的就是一般的JS引用, 强引用会将与之对应的对象保存在内存中, 只有该对象没有任何被强引用时,JavaScript引擎CG 才会销毁该对象并且回收其占用空间。 一旦被回收,无法通过任何弱引用获取该对象。
调用构造函数返回一个实例 , 调用这个实例的deref方法返回引用对象,如果被回收则返回undefined
let obj = {}
let ref = new WeakRef(obj)
let weakRef = ref.deref()
FinalizationRegistry
FinalizationRegistry对象可以让你在对象被垃圾回收时请求一个回调, 不会阻止回收. 实例化一个FinalizationRegistry(callback) 然后调用这个实例的register方法()给目标对象注册回调, 也许永远都不会触发这个回调
// ....
});
// 注册回调 对象 ,包含的值(就是传给回调的参数) , 和移除回调的token
registry.register(obj, value,
tokenObject)
// 移除回调
registry.unregister(tokenObject)
es2020
现在补充2020的内容 不过数字分割符似乎在2020就实现了 现在就不太好验证了
class 私有属性方法
通常实现私有变量的方法是使用闭包的特性 (外部作用域不能访问内部作用域)来实现,现在可以直接用class语法来实现
class APIConnector {
get #apiToken() {
…
}
set #apiToken(value) {
…
}
#checkConnectivity() {
…
}
}
可选链 空值合并
可选链的作用在于 遇到没有的属性就不会再往下了。比如 a?.b?.c, 如果b不存在 那么直接返回 undefined 而不是抛出异常。 注意!!,如果a不存在 ,仍然会抛出异常,因为啊a?.b是要去访问a的b属性 ,如果b不存在则返回undefined,这里a存在是前提。
空值合并运算符 ?? 是一个二元操作符, 可以看做是||的子集。如果它前面的部分为逻辑空 即undefined 或 null
则返回后面的,否则返回前面的。同样可以作为短路运算符,前面的返回值为逻辑空才执行后面的
但是注意不要与 || &&一起使用,因为优先级不确定 。如果要一起用, 用()来确定优先级
动态import()
调用 import()方法 返回一个promise对象。,它不需要依赖 type="module" 的script 标签.
在您希望按照一定的条件或者按需加载模块的时候,动态import() 是非常有用的。而静态型的 import 是初始化加载依赖项的最优选择,使用静态 import 更容易从代码静态分析工具和 tree shaking 中受益。
大数类型 BigInt
js 原本的Number 的范围是 2的53次 -1 。可以通过这个属性 Number.MAX_SAFE_INTEGER ,拿到。结果是 9007199254740991。超过可能会丢失精度。 而BigInt没有限制 任意大的整数。
它在某些方面类似于 Number ,但是也有几个关键的不同点:不能用于 Math 对象中的方法;不能和任何 Number 实例混合运算,两者必须转换成同一种类型。在两种类型来回转换时要小心,因为 BigInt 变量在转换成 Number 变量时可能会丢失精度。
以下操作符可以和 BigInt 一起使用: +、*、-、**、% 。除 >>> (无符号右移)之外的 位操作 也可以支持。因为 BigInt 都是有符号的, >>> (无符号右移)不能用于 BigInt。为了兼容 asm.js ,BigInt 不支持单目 (+) 运算符。
小结 BigInt是一种任意大的整数类型, 不要与Number混用 ,它是有符号位的
Promise.allSettled()
这个方法接受一个promise实例的可迭代对象(就认为是数组),会在全部实例 落定 不管是reject 还是 fulfilled。所以这个也不用catch 或者写reject回调。
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];
Promise.allSettled(promises).
then((results) => results.forEach((result) => console.log(result.status)));
globalThis 顶层上下文
js 在不同的运行环境中,兜底全局 global会有不同的实现, 这个新就是直接告诉我们顶层对象是什么,不用自己去写判断检测。比如在浏览器 globaThis 就是window