JS判断空值只知道“||”?不如来试试这个操作符

今天我们来聊一个JavaScript里非常实用的语法:空值合并运算符 。它的写法是两个问号:??

这个东西有什么用呢?简单说,它帮你处理那些"可能有值,也可能是nullundefined"的情况。

?? 运算符怎么用

空值合并运算符的用法很简单:

ini 复制代码
let result = 左侧值 ?? 右侧值;

它的规则是:

• 如果左侧值 不是null也不是undefined,就返回左侧值

• 如果左侧值nullundefined,就返回右侧值

用这个运算符重写上面的例子:

ini 复制代码
let user = {
  name: null
};

let displayName = user.name ?? "游客";

console.log(displayName); // 输出:游客

一行代码就搞定了!是不是很简洁?

|| 运算符的区别

你可能用过||(逻辑或)运算符来设置默认值:

ini 复制代码
let value = someValue || "默认值";

||??很像,但有一个重要区别:

|| 会在左侧值为 假值 时返回右侧值 • ?? 只在左侧值为 null或undefined 时返回右侧值

JavaScript中的假值包括:

false

0

""(空字符串)

null

undefined

NaN

看一个对比例子:

ini 复制代码
let count = 0;
let price = "";

// 使用 ||
let result1 = count || 10;  // 输出:10(0是假值)
let result2 = price || "未知";  // 输出:"未知"(空字符串是假值)

// 使用 ??
let result3 = count ?? 10;  // 输出:0(0不是null或undefined)
let result4 = price ?? "未知";  // 输出:""(空字符串不是null或undefined)

在实际开发中,如果你希望0false""这些值被保留,就用??。如果你希望所有假值都用默认值替换,就用||

实际场景

场景1:函数参数默认值

javascript 复制代码
function greet(name) {
  // 如果没传name,或者传了null/undefined,就用"朋友"
  let finalName = name ?? "朋友";
  console.log(`你好,${finalName}!`);
}

greet("张三");  // 输出:你好,张三!
greet(null);    // 输出:你好,朋友!
greet();        // 输出:你好,朋友!

场景2:配置对象合并

javascript 复制代码
// 用户设置
let userSettings = {
  theme: null,  // 用户没选主题
  fontSize: 14
};

// 默认设置
let defaultSettings = {
  theme: "light",
  fontSize: 16,
  language: "zh-CN"
};

// 合并设置:优先用用户的,用户没设置就用默认的
let finalSettings = {
  theme: userSettings.theme ?? defaultSettings.theme,
  fontSize: userSettings.fontSize ?? defaultSettings.fontSize,
  language: userSettings.language ?? defaultSettings.language
};

console.log(finalSettings);
// 输出:{ theme: "light", fontSize: 14, language: "zh-CN" }

场景3:链式调用

ini 复制代码
let user = {
  profile: {
    address: {
      city: "北京"
    }
  }
};

// 安全地获取嵌套属性
let city = user?.profile?.address?.city ?? "未知城市";
console.log(city); // 输出:北京

// 如果中间某个属性不存在
let user2 = {
  profile: null
};

let city2 = user2?.profile?.address?.city ?? "未知城市";
console.log(city2); // 输出:未知城市

这里用到了可选链操作符?.,它和??配合使用非常方便。

注意事项

1. 不能直接和&&||一起用

ini 复制代码
// 这样写会报错
let x = a && b ?? c;  // SyntaxError

// 需要加括号
let x = (a && b) ?? c;  // 正确
let y = a && (b ?? c);  // 正确

2. 优先级问题

??的优先级比=高,但比大多数运算符低。为了代码清晰,建议在复杂表达式中使用括号。

ini 复制代码
// 这样写可能不是你想要的
let result = a ?? b && c;

// 加括号更清晰
let result = a ?? (b && c);

3. 在旧版本浏览器中可能不支持

??是ES2020引入的语法。如果你需要支持旧浏览器,可能需要使用Babel等工具进行转换。

什么时候用??

记住这个简单的判断标准:

• 当你只想在变量是nullundefined时才用默认值,用??

• 当你想在所有假值(false0""等)情况下都用默认值,用||

在实际项目中,??通常更适合处理配置、用户输入、API响应等场景,因为这些场景中0false""往往是有效值,不应该被默认值替换。

相关推荐
黄诂多17 分钟前
APP原生与H5互调Bridge技术原理及基础使用
前端
前端市界21 分钟前
用 React 手搓一个 3D 翻页书籍组件,呼吸海浪式翻页,交互体验带感!
前端·架构·github
文艺理科生22 分钟前
Nginx 路径映射深度解析:从本地开发到生产交付的底层哲学
前端·后端·架构
千寻girling23 分钟前
主管:”人家 Node 框架都用 Nest.js 了 , 你怎么还在用 Express ?“
前端·后端·面试
C澒32 分钟前
Vue 项目渐进式迁移 React:组件库接入与跨框架协同技术方案
前端·vue.js·react.js·架构·系统架构
xiaoxue..1 小时前
合并两个升序链表 与 合并k个升序链表
java·javascript·数据结构·链表·面试
清山博客1 小时前
OpenCV 人脸识别和比对工具
前端·webpack·node.js
要加油哦~1 小时前
AI | 实践教程 - ScreenCoder | 多agents前端代码生成
前端·javascript·人工智能
程序员Sunday1 小时前
说点不一样的。GPT-5.3 与 Claude Opus 4.6 同时炸场,前端变天了?
前端·gpt·状态模式
yq1982043011561 小时前
静思书屋:基于Java Web技术栈构建高性能图书信息平台实践
java·开发语言·前端