看了这两篇,ECMAScript12你就懂了(二)
共 2720字,需浏览 6分钟
·
2021-08-07 04:25
三、??= &&= ||=
??=(逻辑空赋值运算符 (x ??= y) 仅在 x 是 nullish (null 或 undefined) 时对其赋值。)
ES11提出了空值合并运算符??(空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。)
const foo = null ?? 'default string';
console.log(foo); // default string
而??=,也从这个基础上又出了这个??=
const a = { duration: 50 };
a.duration ??= 10;
console.log(a.duration);
// 50
a.speed ??= 25;
console.log(a.speed);
// 25
空值合并运算符从左至右求值。(结果非 null 或 undefined 的表达式) ?? expr 被短路求值为左侧表达式,当左侧证明为既非 null 也非 undefined.
语法短路意味着 expr 部分尚未被求值,因此任何与其求值产生的相关副作用都不会生效(例如,如果 expr 是一个函数调用,则该调用将不会发生)。
逻辑空赋值的语法短路也意味着 x ??= y 等价于:
x ?? (x = y); // 理解空值合并运算符之后,再理解就简单啦。
x = x ?? (x = y)
&&=((x &&= y) 仅在 x 是 truthy (非假值,前面有介绍过<即除 false、0、""、null、undefined 和 NaN 以外皆为真值>) 时对其赋值。)
let a = 1;
let b = 0;
a &&= 2;
console.log(a);
// 2
b &&= 2;
console.log(b);
// 0
x &&= y 等价于:
x && (x = y);
x = x && (x = y)
||=((x &&= y) 仅在 x 是 falsy (假值<即false、0、""、null、undefined 和 NaN>) 时对其赋值。)
const a = { duration: 50, title: '' };
a.duration ||= 10;
console.log(a.duration);
// expected output: 50
a.title ||= 'title is empty.';
console.log(a.title);
// "title is empty"
x ||= y 等价于:
x || (x = y);
x = x || (x = y)
四、数字分隔符允许数值字面量中间包含不连续_ ,以提高可读性。
1_000_000_000 // 1000000000
101_475_938.38 // 101475938.38
let a = 1_1; // 11
let a = 1__1 // 错误,只允许一个下划线作为数字分隔符
let a = 1_; // 错误,分隔符不能在尾部
let a = _1; // 错误,分隔符不能在头部
Number(1_1); // 11
Number('1_1'); // NaN
注意:分隔符不能在尾部和头部,只能在数字之间,只允许一个下划线作为数字分隔符,不可连续。
五、WeakRefs & FinalizationRegistryWeakRef对象包含对对象的弱引用,这个弱引用被称为该WeakRef对象的target或者是referent。对对象的弱引用是指当该对象应该被GC回收时不会阻止GC的回收行为。而与此相反的,一个普通的引用(默认是强引用)会将与之对应的对象保存在内存中。只有当该对象没有任何的强引用时,JavaScript引擎GC才会销毁该对象并且回收该对象所占的内存空间。如果上述情况发生了,那么你就无法通过任何的弱引用来获取该对象。
Note: 对于WeakRef对象的使用要慎重考虑,能不使用就尽量不要使用
为什么尽量避免使用
正确使用WeakRef对象需要仔细的考虑,最好尽量避免使用。避免依赖于规范没有保证的任何特定行为也是十分重要的。何时、如何以及是否发生垃圾回收取决于任何给定JavaScript引擎的实现。GC在一个JavaScript引擎中的行为有可能在另一个JavaScript引擎中的行为大相径庭,或者甚至在同一类引擎,不同版本中GC的行为都有可能有较大的差距。GC目前还是JavaScript引擎实现者不断改进和改进解决方案的一个难题。
let obj = {a:1, b:2}; // 只要我们访问 obj 对象,这个对象就不会被垃圾回收
Weakref 实例具有一个方法 deref,该方法返回被引用的原始对象,如果原始对象已被收集,则返回 undefined 对象。
const ref = new WeakRef({ name: '前端编程之家' });
let obj = ref.deref();
if (obj) {
console.log(obj.name); // 前端编程之家
} else{
console.log('target deleted!')
}
FinalizationRegistry 提供了这样的一种方法:当一个在注册表中注册的对象被回收时,请求在某个时间点上调用一个清理回调。(清理回调有时被称为 finalizer )。
使用 FinalizationRegistry 对象可以在垃圾回收器回收对象时执行回调函数。
// 构建监听对象被垃圾回收器清除的回调
const registry = new FinalizationRegistry(heldValue => {
console.log('----', heldValue);
});
const obj = {};
const token = {};
// 注册监听
registry.register(obj, "obj deleted!", token);
// 取消监听
registry.unregister(token);
// ---- obj deleted!
register 参数分别为:需要监听的对象、 执行回调函数的参数、 取消监听用的标识符