逻辑或赋值 ||=
ES2021 引入的 ||= 只在左侧是 falsy 时才赋值:
viewportRect ||= scrollContainer.getBoundingClientRect();
等价于:
if (!viewportRect) {
viewportRect = scrollContainer.getBoundingClientRect();
}
常用于”懒初始化缓存”:第一次访问时计算并保存,后续复用已有值,避免重复执行开销大的操作。
触发赋值的 falsy 值:null、undefined、false、0、''、NaN。
空值合并赋值 ??=
??= 只在左侧是 null 或 undefined 时才赋值:
config.timeout ??= 5000;
等价于:
if (config.timeout === null || config.timeout === undefined) {
config.timeout = 5000;
}
||= 与 ??= 的区别
let x = 0;
x ||= 10;
console.log(x); // 10 ← 0 是 falsy,触发了赋值
let y = 0;
y ??= 10;
console.log(y); // 0 ← 0 不是 nullish,不触发赋值
| 场景 | 推荐 |
|---|---|
| 变量为空对象/数组/字符串时初始化 | ??= |
| 变量为任何假值时初始化 | ` |
| 变量已赋值则不覆盖 | ??=(更安全) |
逻辑与赋值 &&=
&&= 只在左侧是 truthy 时才赋值:
user &&= { ...user, lastLogin: Date.now() };
// 仅当 user 存在时才更新
可选链结合动态属性访问
?.[] 是可选链加计算属性的组合:
const currentValue = projection.user_property?.[attrDef.value];
等价于:
const currentValue =
projection.user_property == null
? undefined
: projection.user_property[attrDef.value];
attrDef.value 是运行时计算的属性名,不能用 ?. 点语法(点语法只能接静态标识符),必须用方括号形式 ?.[]。
// 深层链式安全访问
const val = obj?.a?.b?.[dynamicKey]?.value;
// 任何一级为 null/undefined 都返回 undefined,不会抛错