Article
ES2021 新特性!
逻辑赋值运算符(Logical Assignment Operators)
TC39提案GitHub地址:📖
示例
// 逻辑或赋值
x ||= y;
x || (x = y);
// 逻辑与赋值
x &&= y;
x && (x = y);
// 逻辑空赋值
x ??= y;
x ?? (x = y);
const updateID = user => {
// 传统写法
if (!user.id) user.id = 1
// 或这样
user.id = user.id || 1
// 最新的逻辑或写法
user.id ||= 1
}
function config(options) {
options.duration ??= 100;
options.speed ??= 25;
return options;
}
config({ duration: 125 }); // { duration: 125, speed: 25 }
config({}); // { duration: 100, speed: 25 }
浏览器兼容性

数字分隔符(Numeric Separators)
为了提高数字可读性,可以在数字间使用_(U+005F)作为分隔符📖
示例
10_0000_0000 // 十亿
1_0147_5938.38 // 一亿多
let fee = 123_00; // ¥123 (12300分)
let fee = 1_2300; // ¥12,300 (显然1_2300可读性更好)
0.00_0001 // 百万分之一
1e10_000 // 10^10000
0xA0_B0_C0;
0o2_2_5_6;
使用限制
- 不允许连续超过一个下划线
let n = 123__00; // SyntaxError: Only one underscore is allowed as numeric separator
- 不能出现在数字结尾
let n = 12300_; // SyntaxError: Numeric separators are not allowed at the end of numeric literals
- 不能在前导0后使用
let n = 0_12300; // SyntaxError: Numeric separator can not be used after leading 0.
浏览器兼容性

Promise.any 与 AggregateError
Promise.any()接收一个Promise可迭代对象,只要其中一个Promise被resolve,就返回那个已成功的promise。不会像
Promise.all等待其他promise全部完成,也不会像Promise.race那样总是返回第一个(resolve/reject)的promise。如果没有 fulfilled (成功的) promise,Promise.any() 返回 AggregateError 错误。
示例
Promise.any([
fetch('https://v8.dev/').then(() => 'home'),
fetch('https://v8.dev/blog').then(() => 'blog'),
fetch('https://v8.dev/docs').then(() => 'docs')
]).then((first) => {
// Any of the promises was fulfilled.
console.log(first);
// → 'home'
}).catch((error) => {
// All of the promises were rejected.
console.log(error);
});
// ⬆️ 上述示例中,error为AggregateError
const pErr = new Promise((resolve, reject) => {
reject("总是失败");
});
const pSlow = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "最终完成");
});
const pFast = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "很快完成");
});
Promise.any([pErr, pSlow, pFast]).then((value) => {
console.log(value);
// pFast fulfils first
})
// 期望输出: "很快完成"
浏览器兼容性

String.prototype.replaceAll
replaceAll()方法返回一个新字符串,新字符串所有满足pattern的部分都已被replacement替换。pattern可以是一个字符串或一个RegExp,replacement可以是一个字符串或一个在每次匹配被调用的函数。此方法不会修改调用对象,只是返回一个新的字符串。
示例
// const newStr = str.replaceAll(regexp|substr, newSubstr|function)
'x'.replace('', '_');
// → '_x'
'xxx'.replace(/(?:)/g, '_');
// → '_x_x_x_'
'xxx'.replaceAll('', '_');
// → '_x_x_x_'
// 第一个参数为Regex时,必须加g标志,否则将会触发TypeError
'xxx'.replaceAll(/(?:)/, '_');
// → Uncaught TypeError: String.prototype.replaceAll called with a non-global RegExp argument
浏览器兼容性

WeakRef 和 FinalizationRegistry
对于WeakRef 和 FinalizationRegistry的使用要慎重考虑,能不使用就尽量不要使用!
WeakRef对象允许您保留对另一个对象的弱引用,而不会阻止被弱引用对象被GC回收;FinalizationRegistry对象可以让你在对象被垃圾回收时请求一个回调。
let target = {};
let wr = new WeakRef(target);
//wr and target aren't the same
const registry = new FinalizationRegistry(heldValue => {
// ....
});
registry.register(myObject, "some value", myObject);
// ... 当不再关心myObject的变化时,可以unregister
registry.unregister(myObject);
浏览器兼容性

