前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库空值合并运算符 逻辑或 区别
JavaScript值与类型

?? 和 || 给默认值有什么区别?什么时候该用哪个?

?? 只在左侧是 null 或 undefined 时使用右侧的默认值,|| 对所有假值都会回退。当 0、false、空字符串是合法数据时,用 ?? 才不会把它们误覆盖成默认值。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#值与类型
先看核心答案读代码示例
理解线索

空值和假值是两回事

  1. nullish只有 null 和 undefined 两种
  2. falsy还包括 0、false、空字符串、NaN
  3. 选值逻辑?? 按 nullish 判断,|| 按 falsy 判断

NaN 不是 nullish,?? 会保留它。需要排除 NaN 要另外用 Number.isNaN 检查。

核心回答

先记住这个答案

??(空值合并运算符)和 || 都能给默认值,区别在于判断范围。|| 对左侧做真假判断,所有假值(0、false、空字符串、null、undefined、NaN)都会触发回退。?? 只看左侧是不是 null 或 undefined,是的话才用右侧的默认值,0、false、空字符串这些合法数据不会被覆盖。

  • ?? 只管 null 和 undefined
  • || 还会覆盖 0、false、空字符串
  • ?? 和 || 不加括号混用会报语法错误
  • ??= 只在当前值为空值时才赋值

用代码看清差异

把几种常见的假值和空值同时交给 || 和 ??,就能直观看到两者的区别。

|| 和 ?? 对同一组输入的结果JavaScript
console.log(0 || 100, 0 ?? 100);
console.log(false || true, false ?? true);
console.log('' || 'default', JSON.stringify('' ?? 'default'));
console.log(null || 'fallback', null ?? 'fallback');
console.log(undefined || 'fallback', undefined ?? 'fallback');
查看输出与解释
100 0
true false
default ""
fallback fallback
fallback fallback

前三行是关键:|| 把 0、false、空字符串都替换成了默认值,而 ?? 保留了它们。最后两行 null 和 undefined 的结果一致,因为它们既是假值也是空值,两个运算符都会回退。 第三行的 ?? 结果是空字符串,示例用 JSON.stringify 把它显示成 ""。空字符串是合法值,?? 不会替换它。

什么时候该用哪个

选择标准很简单:如果 0、false、空字符串在你的场景里是合法数据,用 ??。如果你确实想把所有假值都替换成默认值,用 ||。

比如音量控制:用户设置了音量为 0,表示静音。如果用 volume || 50,静音设置会被覆盖成 50。用 volume ?? 50,只有用户没设置过(undefined)或者清空了设置(null)时才回退到 50。

再比如表单里的复选框:checked || true 会把用户主动关闭的 false 覆盖成 true。用 checked ?? true 就不会。

实际项目中大多数给默认值的场景都应该用 ??,因为"没有值"通常指的是 null 和 undefined,不包括 0 和 false。|| 更适合的场景是你确实想排除所有假值,比如 displayName || 'Anonymous'——即使用户名是空字符串也应该显示默认名。

混用限制和 ??= 赋值

?? 不能和 && 或 || 在同一个表达式里不加括号直接混用,否则会抛 SyntaxError。这是语言设计者故意的限制,避免读者猜优先级。

写成 (a ?? b) || c 或 a ?? (b || c) 加上括号就合法了,但要想清楚语义:前者先用 ?? 选出值,再用 || 过滤假值;后者先用 || 过滤,再用 ?? 兜底。两种写法的结果可能不同。

ES2021 还引入了 ??= 赋值运算符,obj.value ??= 'default' 等价于 if (obj.value === null || obj.value === undefined) obj.value = 'default'。它只在当前值为空值时才赋值,已有 0、false、空字符串不会被覆盖。

回答前,多想一步

容易答错的地方

以为 ?? 返回布尔值
和 || 一样,?? 返回的是左值或右值本身,不是 true 或 false。0 ?? 100 返回 0(number 类型),不是 true。
忽略 NaN 不是 nullish
NaN 既不是 null 也不是 undefined,所以 NaN ?? 100 返回 NaN。如果你的计算可能产生 NaN,还需要用 Number.isNaN 单独检查,?? 挡不住它。
试着用自己的话回答

面试官还会怎么问?

??= 和 ||= 有什么区别?

x ??= y 在 x 为 null 或 undefined 时赋值。x ||= y 在 x 为假值时赋值。区别和 ?? 与 || 一样:??= 不动 0 和空字符串,||= 会。

可选链 ?. 和 ?? 怎样配合?

常见写法是 user.profile?.name ?? '匿名'。?. 在链路中遇到 null 或 undefined 时短路返回 undefined,然后 ?? 接上默认值。两个运算符配合可以安全地深入嵌套对象并给兜底值。

为什么不直接扩展 || 的行为,而是新增了 ???

改 || 的行为会破坏大量已有代码。很多老代码就是利用 || 对假值的覆盖特性来工作的,比如 name || 'default'。新增一个运算符可以让开发者按需选择,不影响已有的逻辑。

从一道题,走向一组知识

把知识连起来

值与类型

JavaScript 的 Number 在内存里是怎么存的?符号、指数、尾数各占几位?

理解 0 和 -0 都不是 nullish,可以搞清浮点特殊值和空值判断的关系。

值与类型

parseInt 有哪些坑?为什么 ['1', '2', '3'].map(parseInt) 结果不对?

parseInt 返回 NaN 时不会被 ?? 拦住,需要单独校验解析结果。

参考资料

  • JavaScript:值与类型参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 用代码看清差异
  3. 什么时候该用哪个
  4. 混用限制和 ??= 赋值
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑