一、核心概念
-
作用
当左侧表达式为null
或undefined
时,返回右侧的默认值;否则返回左侧的值。 -
与
||
的区别||
会对 所有假值(如0
、''
、false
、NaN
)触发默认值。??
仅对null
或undefined
触发默认值,保留其他假值的语义。
console.log(0 || 5); // 5(0 是假值) console.log(0 ?? 5); // 0(0 不是 null/undefined)
二、语法规则
leftExpr ?? rightExpr
- 短路特性:若
leftExpr
不是null/undefined
,直接返回左侧值,不计算右侧。 - 优先级:低于
||
和&&
,但高于三元运算符? :
。建议用()
明确优先级。
三、使用场景
1. 变量默认值
const userInput = null;
const name = userInput ?? "Anonymous"; // "Anonymous"
2. 函数参数默认值
function greet(message) {
const text = message ?? "Hello";
console.log(text);
}
greet(null); // "Hello"
greet(undefined); // "Hello"
greet(""); // ""(保留空字符串)
3. 对象属性安全访问
const config = {
apiUrl: null,
timeout: 0
};
const url = config.apiUrl ?? "https://default.api";
const timeout = config.timeout ?? 5000; // 0 被保留
4. 结合可选链 ?.
使用
const user = {
profile: null
};
const username = user?.profile?.name ?? "Guest"; // "Guest"
四、进阶用法
1. 多级空值合并
const a = null;
const b = undefined;
const c = "Fallback";
const result = a ?? b ?? c; // "Fallback"
2. 与解构赋值结合
const settings = { theme: null };
const { theme = "light", fontSize = 16 } = settings;
// theme 使用 ?? 逻辑,fontSize 使用 = 默认值
3. 动态默认值
let defaultPort;
const port = process.env.PORT ?? (defaultPort = 3000);
五、注意事项
-
不可直接用于未声明的变量
// 错误示例(需确保变量已声明) const value = undeclaredVar ?? 10; // ReferenceError
-
与
||
混用时的优先级const a = null || undefined ?? "default"; // SyntaxError const b = (null || undefined) ?? "default"; // "default"
-
浏览器兼容性
- 支持 ES2020+ 的环境(Chrome 80+, Firefox 72+, Node.js 14+)。
- 旧环境需通过 Babel 插件
@babel/plugin-proposal-nullish-coalescing-operator
转译。
六、性能优化
- 避免重复计算:若右侧是复杂表达式,用函数封装避免副作用。
const value = input ?? computeDefault(); // computeDefault() 仅在需要时执行
七、替代方案(旧代码兼容)
// 使用三元运算符模拟 ??
const value = (left !== null && left !== undefined) ? left : right;
总结
运算符 | 触发默认值的条件 | 适用场景 |
---|---|---|
?? | null 或 undefined | 保留其他假值(如 0 、'' ) |
` | ` |
掌握 ??
能显著提升代码可读性,尤其在处理 API 响应、配置项等场景时,能更精准地控制默认值逻辑。