Skip to content

JavaScript 中 ?? 和 || 操作符的区别

问题概述

在 JavaScript 中,当需要为变量提供默认值时,开发者经常需要在 ??(空值合并操作符)和 ||(逻辑或操作符)之间做出选择。虽然它们在某些情况下行为相同,但在处理 falsy 值(假值)时存在关键差异。

核心区别

关键区别

  • || 操作符:当左侧操作数为任何 falsy 值 时返回右侧操作数
  • ?? 操作符:仅当左侧操作数为 null 或 undefined 时返回右侧操作数

JavaScript 中的 falsy 值包括:false0''(空字符串)、nullundefinedNaN。而 nullish 值仅指 nullundefined

代码示例对比

js
console.log(0 || "default")        // "default"
console.log('' || "default")       // "default" 
console.log(false || "default")    // "default"
console.log(null || "default")     // "default"
console.log(undefined || "default")// "default"
js
console.log(0 ?? "default")        // 0
console.log('' ?? "default")       // ""
console.log(false ?? "default")    // false
console.log(null ?? "default")     // "default"
console.log(undefined ?? "default")// "default"

实际应用场景

场景一:表单处理

处理表单数据时,空字符串可能是有效输入,不应被默认值替换:

js
// 如果用户清空电话号码字段,会被替换为默认值
const phone = document.querySelector('#phone').value || '未知号码'
// 空字符串 '' 是 falsy,会返回 '未知号码'
js
// 只有 null 或 undefined 时才会使用默认值
const phone = document.querySelector('#phone').value ?? '未知号码'
// 空字符串 '' 会被保留

场景二:数值计算

处理可能为 0 的数值时:

js
function addYears(years) {
  const yearsToAdd = years || 1 // 如果 years=0,会变成 1
  return currentAge + yearsToAdd
}

addYears(0) // 不会保持 0 年增加
js
function addYears(years) {
  const yearsToAdd = years ?? 1 // 只有 null/undefined 时使用默认值
  return currentAge + yearsToAdd
}

addYears(0) // 正确保持 0 年增加

场景三:API 数据处理

从接口获取数据时,区分"未提供"和"空值":

js
// 从API获取用户数据
const userData = await fetchUserData()

// 如果API返回中缺少score字段或显式设置为null/undefined
const score = userData.score ?? 0 // 仅对nullish值使用默认值

// 如果score是空字符串或0,它们会被保留而不是被替换

何时使用哪个操作符

选择指南

  • 使用 ??:当你只想排除 nullundefined,但需要保留其他 falsy 值(如 0false"")时
  • 使用 ||:当你需要排除所有 falsy 值,包括 0""falsenullundefined

兼容性说明

?? 操作符是 ES2020 中引入的现代 JavaScript 特性:

  • Node.js 14+ 原生支持
  • TypeScript 3.7+ 支持
  • 旧版环境需要通过 Babel 等工具进行转译

总结对比表

| 场景 | || 结果 | ?? 结果 | 推荐选择 | |------|-----------|-----------|----------| | null \| undefined | 使用默认值 | 使用默认值 | 两者相同 | | 0 | 使用默认值 | 保留 0 | ?? | | "" (空字符串) | 使用默认值 | 保留 "" | ?? | | false | 使用默认值 | 保留 false | ?? | | 其他 truthy 值 | 保留原值 | 保留原值 | 两者相同 |

在实际开发中,大多数情况下推荐使用 ?? 操作符,因为它能更精确地处理各种边界情况,避免意外的类型转换。只有当明确需要排除所有 falsy 值时,才使用 || 操作符。