??= 仅在左侧为 null 或 undefined 时赋值,精准设默认值,避免误覆 0/false/'' 等假值;支持短路求值、链式补全,但不可与可选链联用。

逻辑空赋值运算符(??=)在 JavaScript 中用于“仅当左侧操作数为 null 或 undefined 时”,才将右侧的值赋给左侧变量。它比 ||= 更精准,避免了对 0、false、''(空字符串)等假值的误覆盖,特别适合设定真正意义上的“默认值”。
只在空值时设默认值
与 ||= 不同,??= 严格区分“空值”(null/undefined)和“假值”。例如:
const opts = { timeout: 0 };
opts.timeout ??= 5000; // 不执行赋值,因为 0 是有效值
console.log(opts.timeout); // 输出:0
而用 ||= 就会错误地把 0 当作“需兜底”,导致默认值被意外覆盖。
简化配置对象初始化
常用于函数参数或配置对象的懒初始化,避免重复判断:
立即学习“Java免费学习笔记(深入)”;
- 直接为可能未定义的属性设置默认值:
config.db ??= { host: 'localhost', port: 5432 }; - 配合解构使用更安全:
const { retries = 3 } = options;是解构默认值,options.retries ??= 3;是原地补缺,二者适用场景不同 - 适合链式结构中某层缺失时补全:
user.profile ??= {};,再继续设user.profile.avatar ??= '/default.png';
避免副作用和重复计算
??= 是短路运算符,右侧表达式仅在需要赋值时才求值,适合含函数调用或开销较大的默认值:
-
cache.data ??= fetchDataFromAPI();—— 只有 cache.data 为空时才发起请求 -
logger.level ??= getDefaultLogLevel();—— 避免每次调用都执行默认级别推导 - 相比
if (x == null) x = y();,语法更简洁,语义更明确
注意与可选链(?.)的协同使用
处理深层嵌套属性时,??= 不能直接用于带可选链的左侧(如 obj?.prop ??= value 会报错),需先确保目标位置可写:
// ❌ 错误:语法错误
// obj?.settings?.theme ??= 'light';
// ✅ 正确做法:分步确保路径存在
obj.settings ??= {};
obj.settings.theme ??= 'light';
也可封装成工具函数,但日常开发中分步赋值已足够清晰可靠。










