??
和 ||
的区别详解
在 JavaScript/TypeScript 中,??
(空值合并运算符)和 ||
(逻辑或运算符)都用于提供默认值,但它们在处理不同值时有关键区别。
核心区别
运算符 | 名称 | 触发条件 | 处理假值的方式 |
---|---|---|---|
?? |
空值合并运算符 | 仅当左侧为 null 或 undefined |
保留假值(0、''等) |
|| |
逻辑或运算符 | 当左侧为 任何假值(falsy) | 跳过所有假值 |
假值(falsy)列表
在 JavaScript 中,假值包括:
false
0
''
(空字符串)null
undefined
NaN
详细比较
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!