?? 和 || 的区别详解
在 JavaScript/TypeScript 中,??(空值合并运算符)和 ||(逻辑或运算符)都用于提供默认值,但它们在处理不同值时有关键区别。
核心区别
| 运算符 | 名称 | 触发条件 | 处理假值的方式 |
|---|---|---|---|
?? |
空值合并运算符 | 仅当左侧为 null 或 undefined |
保留假值(0、''等) |
|| |
逻辑或运算符 | 当左侧为 任何假值(falsy) | 跳过所有假值 |
假值(falsy)列表
在 JavaScript 中,假值包括:
false0''(空字符串)nullundefinedNaN
详细比较
1. 处理 null/undefined
两者行为相同:
null ?? 'default' // 'default'
undefined ?? 'default' // 'default'null || 'default' // 'default'
undefined || 'default' // 'default'
2. 处理数字 0
关键区别点:
0 ?? 10 // 0(保留0)
0 || 10 // 10(跳过0)
3. 处理空字符串 ''
'' ?? 'default' // ''(保留空字符串)
'' || 'default' // 'default'(跳过空字符串)
4. 处理布尔值 false
false ?? true // false(保留false)
false || true // true(跳过false)
5. 处理 NaN
NaN ?? 100 // NaN(保留NaN)
NaN || 100 // 100(跳过NaN)
实际应用场景
适合使用 ?? 的情况:
-
当 0、空字符串或false是有效值 时:
// 分页组件 const currentPage = userInput ?? 1; // 0是有效输入// 温度显示 const temperature = sensorValue ?? 20; // 0是有效温度 -
需要明确区分 空值(null/undefined) 和 假值(0、''等):
const fontSize = settings.fontSize ?? 16; // 0 表示小号字体,不应被替换
适合使用 || 的情况:
-
当 所有假值都应视为无效 时:
const username = input || 'Anonymous'; // 空字符串、null、undefined 都视为无效 -
布尔值检查:
const isEnabled = featureFlag || false;
Vue 中的使用示例
<template><!-- 显示消息:空消息显示"暂无消息" --><div>{{ message || '暂无消息' }}</div><!-- 显示评分:0分是有效分数 --><div>评分:{{ rating ?? '未评分' }}</div><!-- 显示评论数:0评论是有效值 --><div>评论:{{ commentCount ?? '无' }}</div>
</template><script setup lang="ts">
import { ref } from 'vue';const message = ref('');
const rating = ref(0);
const commentCount = ref(0);
</script>
优先级与结合性
-
??和||可以混合使用,但要注意优先级:// 需要括号明确优先级 const value = (a ?? b) || c; const value = a ?? (b || c); -
??不能直接与&&或||组合使用:// 语法错误 a || b ?? c; a ?? b || c;// 正确写法 (a || b) ?? c; a ?? (b || c);
总结表
| 值 | a ?? b 结果 | a || b 结果 |
|-----------------|---------------|---------------|
| null | b | b |
| undefined | b | b |
| 0 | 0 | b |
| '' | '' | b |
| false | false | b |
| NaN | NaN | b |
| 其他真值 | a | a |
简单记忆:
- 用
??当你想保留0、''、false等有效值 - 用
||当你想跳过所有假值(包括0、''等)
根据你的具体需求选择正确的运算符,可以避免很多边界情况的 bug!
