String.prototype.replaceAll
replace()只有使用全局标志g才能替换所有匹配的子串,否则只替换第一个匹配子串。replaceAll()默认替换所有匹配的子串。
let str = "爱生活,爱自由";
console.log(str.replace("爱", "love")); // love生活,爱自由
console.log(str.replace(/爱/, "love")); // love生活,love自由
console.log(str.replace(/爱/g, "love")); // love生活,love自由
// replaceAll也可以使用正则进行匹配,但非全局匹配(/g)则会抛出异常
console.log(str.replaceAll("爱", "love")); // love生活,love自由
console.log(str.replaceAll(/爱/g, "love")); // love生活,love自由
console.log(str.replaceAll(/爱/, "love")); // Uncaught TypeError: String.prototype.replaceAll called with a non-global RegExp argument
Promise.any()
当Promise列表中的任意一个promise成功resolve则进入then,返回的结果为第一个resolve的结果状态,如果所有的promise都reject,则抛出异常表示所有请求失败。
const promise1 = new Promise((resolve, reject) => {
setTimeout(reject, 300, 'promise1');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 400, 'promise2');
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'promise3');
});
Promise.any([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
简单的说,Promise.all()是一个都不能少,Promise.race()是先到先得,Promise.any()则是对一个就行。
逻辑赋值运算符(Logical assignment operators)
逻辑赋值运算符将逻辑运算(例如??,&&或||)与赋值(例如=)结合使用
逻辑与赋值(&&=)
let a = 0;
const b = 2;
a &&= b; // a为0
// 等价于
a && (a = b);
// or
if (a) {
a = b;
}
逻辑或赋值(||=)
let a = 0;
const b = 2;
a ||= b; // a为2
// 等价于
a || (a = b);
// or
if (!a) {
a = b;
}
逻辑 nullish 赋值 (??=)
??是nullish(空值)合并运算符,(null、undefined、false、NaN、0、"" (空字符串))中只有null和undefined是是nullish。
let a = 0;
let b = null;
let c = "";
a ??= 2; // a为0
b ??= 2; // b为2
c ??= 2; // c为""
// 等价于
a ?? (a = 2);
// or
if (a === null || a === undefined) {
a = 2;
}
数值分隔符(Numeric separators)
数字分隔符,可以在数字之间创建可视化分隔符,通过_下划线来分割数字,使数字更具可读性。
const num = 123_45;
console.log(num); // 12345
WeakRefs
使用WeakRefs的Class类创建对对象的弱引用,弱引用是指当该对象应该被GC回收时不会阻止GC的回收行为。WeakRef实例有一个方法deref,返回引用的原始对象,如果原始对象被回收,则返回undefined。
let obj = {
"a": 1,
"b": "2",
"c": null
};
const ref = new WeakRef(obj);
console.log(ref); // WeakRef {}
console.log(ref.deref()); // {a: 1, b: "2", c: null}
// 被gc回收后
console.log(ref.deref()); // undefined
FinalizationRegistry
FinalizationRegistry接收一个注册器回调函数,可以利用该注册器为指定对象注册一个事件监听器,当这个对象被垃圾回收后会触发监听的事件。
const registry = new FinalizationRegistry(val => {
console.log(val);
});
let obj = {
"a": 1,
"b": "2",
"c": null
};
// 如果obj被回收了就会调用清理回调,这个时候传递一个保留值,这个保留值不限制类型。但是如果这个值是一个对象,则注册表会保留对该值的强引用,以便将其传递给回调函数。
registry.register(obj, "The object has been garbage collected.");
obj = null;
如果在注册事件时传递第三个值,可以通过unregister()对注册的回调事件进行清理,这个值将作为在调用注册表的注销函数注销对象时将使用的注销令牌, 注册表仅保留对取消注册令牌的弱引用。这个值必须是一个对象,因此通常使用对象本身。
const registry = new FinalizationRegistry(val => {
console.log(val);
});
let obj = {
"a": 1,
"b": "2",
"c": null
};
registry.register(obj, "The object has been garbage collected.", obj);
registry.unregister(obj); // 清理之后gc将不会触发回调
obj = null;