可选链运算符和空值合并运算符的使用

摘要:前端开发经常遇到访问对象深层属性报错 Cannot read property 'xxx' of undefined/null,?. 可选链和 ?? 空值合并运算符就是专门解决这类问题。很多人容易把 ?? 和 || 搞混,本文结合思维导图,讲清语法、区别、业务场景和踩坑点。

一、空值合并运算符 ??

语法

复制代码
变量A ?? 变量B

大白话:如果 A 是 null 或者 undefined,就使用 B;否则就使用 A 本身。

⚠️重点:?? 只对 null、undefined 生效 。 0、''空字符串、false 会被认为是有效原值,不会被替换。

代码示例

复制代码
console.log(null ?? 100);      // 100,null走后面
console.log(undefined ?? 100); // 100,undefined走后面

console.log(0 ?? 100);        // 0,0不是null/undefined,直接返回0
console.log('' ?? 100);       // '',空字符串直接返回空字符串
console.log(false ?? 100);    // false,false直接返回false

和逻辑或 || 的核心区别

  • ||:虚假值判断 ,只要是0、''、false、null、undefined全部认为是假,直接使用后面的值。
  • ??:只认 null、undefined ;0、''、false视为有效数据,保留原值。

业务坑点 :后端返回数字 0、空字符串,不能被默认值覆盖,这时候必须用??,不能用||。

| 表达式 | 使用 || 结果 | 使用??结果 | | ---- | ---- | ---- | |0 || 100|100|0| |'' || ' 默认 '|' 默认 '|''| |false || true|true|false| |null || 100|100|100| |undefined ||100|100|100|

业务场景

场景 1:接口返回数据兜底

接口字段可能返回null/undefined,给默认值,保留 0、空字符串这类合法业务值。

复制代码
// res.data 为 null/undefined 时给空对象,0就保留0
const info = res.data ?? {}
const count = info.count ?? 0
场景 2:和可选链?.组合(高频)

二者搭配,是对象容错的黄金组合。

复制代码
// user不存在,?.返回undefined,再通过??设置默认名称
const userName = user?.name ?? "匿名用户"

二、可选链操作符 ?.

用途:解决深层对象属性判空痛点 。对象不存在就返回undefined,不会抛出报错,防止访问属性层级过深控制台崩错。

基础语法

  1. 对象属性访问 obj?.prop

    const user = null
    console.log(user?.name) // undefined,不会报错

  2. 方括号形式 obj?.[key]

    const user = null
    let key = "phone"
    console.log(user?.[key]) // undefined

搭配空值合并 ?? 一起使用

  • ?.:对象不存在,返回undefined;

  • ??:拿到undefined,设置兜底默认值。

    const user = null
    // user为null,?.得到undefined,??赋值默认昵称
    const nickName = user?.info?.nickname ?? "游客用户"
    console.log(nickName) // 游客用户

常见业务场景

接口返回的数据结构不确定,对象层级很深,不需要层层if判断是否存在。 不使用可选链,冗余写法

复制代码
// 传统写法,层层判断,代码繁琐
let nickName = "游客用户"
if(user && user.info && user.info.nickname){
    nickName = user.info.nickname
}

使用可选链,一行搞定

复制代码
const nickName = user?.info?.nickname ?? "游客用户"

三、重要踩坑总结

  1. ||会把0、''、false覆盖,涉及数字计数、状态布尔值优先用??。
  2. ?.只是防止报错,返回undefined,想要兜底默认值,必须搭配??。
  3. ??仅仅识别null、undefined,0、空字符串、布尔 false 不会触发兜底。
  4. 二者组合?. + ??,是前端处理接口对象容错的标准写法。

四、简单完整业务示例

复制代码
//模拟后端返回,user为null
const res = {
    user: null
}

//获取用户昵称,没有给默认游客
const nick = res.user?.base?.nick ?? '游客'
console.log(nick) //游客

//模拟后端返回count = 0,业务代表数量为0,不能被||覆盖
const data = { count:0 }
const num = data.count ?? 10
console.log(num) //0,保留业务真实0,不会变成10

小提示:这两个 ES2020 新语法,现代浏览器全部支持;如果要兼容老旧浏览器,需要 babel 转译。

相关推荐
CDwenhuohuo10 小时前
electron pc项目打包成桌面端
前端·javascript·electron
前端大斗师10 小时前
「大于 1000」把 1000 元那单也算进去了:我在 Vue3 订单页对了 10 句话
前端·人工智能·typescript·大模型·原力计划
Jmyd012311 小时前
用 Web VR 引擎搭建 3D 虚拟展厅:从素材上云到多端实时渲染的完整数据链路
前端·3d·vr·三维数字化
刘天远11 小时前
Agent成本核算实现:事件表、状态分布与Python归集
前端·数据库·人工智能·python
欣欣之王来了12 小时前
开发环境准备:Node.js、npm、VS Code安装配置
前端·学习·架构·项目·vue3教程
xiaolinudao12312 小时前
将多个 Excel 表格中的数据合并到单个表中|6 种实现方案全解析
java·前端·excel
计算机毕设定制辅导-无忧学长12 小时前
《校园食堂在线订餐小程序的设计与实现》
java·vue.js·spring boot·微信小程序·uniapp·校园食堂在线订餐小程序
LRL_12 小时前
跨平台 Node 模块安装指南:如何利用 pnpm/npm 配置`supportedArchitectures` 锁定平台依赖
前端·npm·node.js
EatFan13 小时前
React 项目踩坑实录:useEffect 闭包陷阱、Context 性能陷阱与 React 18 升级避坑排查手册
前端·javascript·react.js·react·react hooks·useeffect·闭包陷阱
风骏时光牛马13 小时前
企业业务运营信息数据库
前端