内容简介
- 逻辑赋值运算符(明雪讲过:https://cc.komect.com/website/blog/detail?id=296 关键词:运算符)
- 数字分隔符
-
Promise.any()
(Promise拓展) replaceAll
逻辑赋值运算符
1. 前置知识点:
运算符优先级
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
falsy值 (虚值):https://developer.mozilla.org/zh-CN/docs/Glossary/Falsy
这意味着当 JavaScript 期望一个布尔值,并被给与下面值中的一个时,它总是会被当做 false。
if (false)
if (null)
if (undefined)
if (0)
if (0n)
if (NaN)
if ('')
if ("")
if (``)
if (document.all) //document.all 虽然是一个对象,但其转换为 boolean 类型是 false
空值合并运算符:空值合并操作符(
??
)是一个逻辑操作符,当左侧的操作数为null
或者undefined
时,返回其右侧操作数,否则返回左侧操作数。
2. 定义
逻辑赋值操作符将逻辑操作(&&、||或??)与赋值表达式组合在一起。
现有的的运算符,其工作方式都可以如此来理解
表达式:a op= b
等同于:a = a op b
例如:a+=b a=a+b
逻辑赋值运算符则按照下面的方式理解
x ||= y;
x || (x = y); // x 为 falsy 则 x=y
x &&= y;
x && (x = y); // x 为 真值 则 x=y
x ??= y;
x ?? (x = y); // x 为 null或undefined 则 x=y
3. 应用
适用于赋值默认值的场景
数字分隔符
1. 定义
数字分隔符,可以在数字之间创建可视化分隔符,通过_下划线来分割数字,使数字更具可读性
const num = 1_000_000;
console.log(num); //1000000
分隔符可以用于数字的整数部分和小数部分。分隔符不仅可以用在整数和浮点数中,也可以用在二进制、十六进制、八进制字面量中。分隔符也适用于BigInt数字。
2. 应用
增加代码可读性,方便读取数据
Promise.any()
1. 前置知识点:
Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
Promise.all 全部resolve回调结束或者任意一个reject。
Promise.allSettled 返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。
总结:
allSettled
:当您有多个彼此不依赖的异步任务成功完成时,或者您总是想知道每个promise的结果时
all
:彼此相互依赖或者在其中任何一个reject时立即结束
2. 定义
Promise.any()
接收一个Promise
可迭代对象,只要其中的一个promise
成功,就返回那个已经成功的promise
。如果可迭代对象中没有一个promise
成功(即所有的promises
都失败/拒绝),就返回一个失败的promise
和AggregateError
类型的实例,它是Error
的一个子类,用于把单一的错误集合在一起。
与race对比示例
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
})
// 期望输出: "很快完成"
Promise.race([pErr, pSlow, pFast]).then((value) => {
console.log(value);
// pErr rejected first
})
// 期望输出: "总是失败"
AggregateError异常示例
const pErr = new Promise((resolve, reject) => {
reject('总是失败');
});
Promise.any([pErr]).catch((err) => {
console.log(err);
})
// 期望输出: "AggregateError: All promises were rejected"
3. 应用
显示第一张已加载的图片,我们有一个获取图片并返回 blob 的函数,我们使用 Promise.any() 来获取一些图片并显示第一张有效的图片(即最先 resolved 的那个 promise)。
4. 扩展 (Promise时间线)
Promise:ES6(2015)
Promise.finally():ES9(2018)
在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise
是否成功完成后都需要执行的代码提供了一种方式。这避免了同样的语句需要在then()
和catch()
中各写一次的情况。
Promise.allSettled:ES11(2020)
Promise.any:ES12(2021)
String.prototype.replaceAll
1. 定义
replaceAll()
方法返回一个新字符串,新字符串所有满足pattern
的部分都已被replacement
替换。pattern
可以是一个字符串或一个RegExp
,replacement
可以是一个字符串或一个在每次匹配被调用的函数。
!!!可以不用正则匹配去全局替换了
const str = "Backbencher sits at the Back";
const newStr = str.replace("Back", "Front");
console.log(newStr); // "Frontbencher sits at the Back"
const str = "Backbencher sits at the Back";
const newStr = str.replace(/Back/g, "Front");
console.log(newStr); // "Frontbencher sits at the Front"
const str = "Backbencher sits at the Back";
const newStr = str.replaceAll("Back", "Front");
console.log(newStr); // "Frontbencher sits at the Front"
const str = "Backbencher sits at the Back";
const newStr = str.replaceAll(/Back/g, "Front");
console.log(newStr); // "Frontbencher sits at the Front"
WeakRef
1. 前置知识点
垃圾回收机制 https://cc.komect.com/website/blog/detail?id=216 (珊珊讲过 关键词:垃圾回收)
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Memory_Management
WeakSet对象允许你将弱保持对象存储在一个集合中。
弱引用Set。只能存储对象,不能存储其他类型。且只保持对其中对象的弱引用,若外部无对此对象的引用,或者对象被删除,则WeakSet中将不再有此对象。
因为成员都是弱引用,随时可能消失,遍历不能保证成员的存在。所以 WeakSet 不能遍历。
WeakMap 对象是一组键/值对的集合,其中的键是弱引用的。其键必须是对象,而值可以是任意的。
相比之下,原生的 WeakMap 持有的是每个键对象的“弱引用”,这意味着在没有其他引用存在时垃圾回收能正确进行。原生 WeakMap 的结构是特殊且有效的,其用于映射的 key 只有在其没有被回收时才是有效的。
正由于这样的弱引用,WeakMap
的 key 是不可枚举的 (没有方法能给出所有的 key)。如果key 是可枚举的话,其列表将会受垃圾回收机制的影响,从而得到不确定的结果。因此,如果你想要这种类型对象的 key 值的列表,你应该使用 Map
。
WeakMap和WeakSet的作用,可以用来存储DOM节点,保持与DOM节点相关的数据,当DOM节点被删除后,集合中的数据自动删除,
这样就不必担心移除DOM节点时的内存泄漏了。
2. 定义
WeakRef对象允许您保留对另一个对象的弱引用,而不会阻止被弱引用对象被GC回收
弱引用的主要用途是实现大型对象的缓存或映射。在这种情况下,我们不希望长期保留大量的内存来保存这种很少使用的缓存或映射。我们可以让内存很快被垃圾回收,以后如果我们再次需要它,我们可以生成一个新的缓存。
在一个DOM元素中启动一个计数器,当这个元素不存在时停止。
class Counter {
constructor(element) {
// Remember a weak reference to the DOM element
this.ref = new WeakRef(element);
this.start();
}
start() {
if (this.timer) {
return;
}
this.count = 0;
const tick = () => {
// Get the element from the weak reference, if it still exists
const element = this.ref.deref();
if (element) {
element.textContent = ++this.count;
} else {
// The element doesn't exist anymore
console.log("The element is gone.");
this.stop();
this.ref = null;
}
};
tick();
this.timer = setInterval(tick, 1000);
}
stop() {
if (this.timer) {
clearInterval(this.timer);
this.timer = 0;
}
}
}
const counter = new Counter(document.getElementById("counter"));
counter.start();
setTimeout(() => {
document.getElementById("counter").remove();
}, 5000);
- 尽量避免使用
正确使用WeakRef对象需要仔细的考虑,最好尽量避免使用。避免依赖于规范没有保证的任何特定行为也是十分重要的。何时、如何以及是否发生垃圾回收取决于任何给定JavaScript引擎的实现。GC在一个JavaScript引擎中的行为有可能在另一个JavaScript引擎中的行为大相径庭,或者甚至在同一类引擎,不同版本中GC的行为都有可能有较大的差距。GC目前还是JavaScript引擎实现者不断改进和改进解决方案的一个难题。
babel
https://babeljs.io/docs/en/babel-plugin-proposal-logical-assignment-operators
https://babeljs.io/docs/en/babel-plugin-proposal-numeric-separator
参考文章
https://www.ahwgs.cn/lingrenxingfendesandaxinjavascript-es-2021es-12gongneng.html
https://blog.csdn.net/pz1021/article/details/115242973
https://mp.weixin.qq.com/s/tZ5pnyl1R-7Q60-QHtb-jw
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakRef