都25年了,快用?.替代&&,??替代||

我将创建一个小知识点系列文章,每篇文章只围绕一个很小的知识点展开,阅读成本低,压力小,目的是能够以比较少的时间对一个知识点进行比较扎实的理解和掌握。

最近阅读部门其他人写的代码的时候,发现还有人没有使用链判断运算符?.和Null判断运算符??,而还是使用原始的判断方式。所以我想说都25年了,竟然还不知道这么方便的运算符吗,还不快快用起来!哈哈哈~

一、链判断运算符?.

当我们读取一个对象内部比较深层的属性的时候,往往需要判断一下,属性的上层对象是否存在,以前的写法会是下面这种判断方式:

js 复制代码
// 错误的写法
const  firstName = message.body.user.firstName || 'default';

// 正确的写法
const firstName = (message
  && message.body
  && message.body.user
  && message.body.user.firstName) || 'default';

但是这种写法需要层层判断对象是否存在,很是麻烦。而使用链判断运算符?.,简化后的写法如下:

js 复制代码
const  firstName = message?.body?.user?.firstName || 'default';

?表示判断左侧的对象是否存在,如果存在则继续进行后面点.的读取的操作。如果左侧的对象是null或undefined,则不再往下读取,直接返回undefined。

三种写法

  • obj?.prop // 对象属性是否存在
  • obj?.[expr] // 同上
  • func?.(...args) // 函数或对象方法是否存在

对于对象的属性和方法都可以使用链判断运算符进行读取。注意该运算符是?.构成的整体?.?表示判断左侧的对象是否存在,.表示继续向下读取对象的属性或方法或者进行方法的调用。

如上的后两种写法,通过方括号读取属性和进行方法调用的时候,我们可能习惯性的会只写一个?进行判断,这里需要注意一下哈。

注意

避免过度使用,不要用于已确定存在的对象

链判断运算符的核心作用是 "处理可能不存在的对象 / 属性",如果对象或属性是明确存在的(如自己定义的普通对象、框架提供的必选参数),则不需要进行链判断,过度使用?.会增加代码冗余。 如下是一个错误示例:

js 复制代码
// 自己定义的obj,明确存在name属性,无需使用?.
const obj = { name: '张三' };
const name = obj?.name; // 多余的?.,应直接写obj.name

不能用于左侧赋值

?.仅支持 "读取属性 / 调用方法",不允许用于赋值语句的左侧。这是因为链判断的核心是 "安全读取",而赋值需要明确的目标对象,若左侧对象不存在,赋值行为本身就是无效的。如下是一个错误示例:

js 复制代码
// 语法错误:Uncaught SyntaxError: Invalid left-hand side in assignment
message?.body?.user?.firstName = '张三';

二、Null判断运算符

读取对象属性时,如果某个属性的值是null或undefined,也就是不存在或者未指定初始值的情况,有时需要为它们指定默认值。

以前的做法是通过||短路运算符指定默认值,当左侧的计算值为false的时候,则会读取||右侧的值。但是属性的值如果为空字符串或false或0,都会被转为false值,此时默认值都会生效。但这不是我们所期望的,有的时候我们就是想将值设置为空字符串或false或为0啊。这个时候就可以使用Null判断运算符进行处理。

Null判断运算符??的行为类似短路运算符||,但是只有运算符左侧的值为null或undefined时,才会返回右侧的值,这正是我们期望的设置默认值的情况。

js 复制代码
const headerText = response.settings.headerText ?? 'Hello, world!';
const animationDuration = response.settings.animationDuration ?? 300;
const showSplashScreen = response.settings.showSplashScreen ?? true;

如上.headerText可能为空字符串"",.animationDuration可能为0.showSplashScreen可能为false,使用??配置默认值的时候,均不会影响这些值的生效。

三、两个运算符的结合使用

将链判断运算符?.和Null判断运算符??结合使用是比较常用的方式。前者进行属性的判断和读取,当读取不到值的时候,则通过后者进行默认值的设置。

js 复制代码
const headerText = response.settings?.headerText ?? 'Hello, world!';
const animationDuration = response.settings?.animationDuration ?? 300;
const showSplashScreen = response.settings?.showSplashScreen ?? true;

如上response.settings对象上可能不存在.headerText.animationDuration.showSplashScreen三个配置项属性,因此先通过?.进行判断,并且分别为三个配置项通过??设置了默认值,这样的读取方式才更为安全。

最后

希望对大家有所帮助,并给予点赞哈~

相关推荐
做怪小疯子14 小时前
JavaScript 中Array 整理
开发语言·前端·javascript
六元七角八分14 小时前
CSDN文章如何转出为PDF文件保存
开发语言·javascript·pdf
香香爱编程14 小时前
Electron里的electron-window-state 使用
前端·javascript·vue.js·vscode·electron·前端框架
涔溪14 小时前
Vue 中实现 PDF 文件上传
javascript·vue.js·pdf
JohnYan14 小时前
Bun技术评估 - 29 Docker集成
javascript·后端·docker
玉宇夕落15 小时前
JavaScript 执行状态全景图:从调用栈到事件循环,深入理解异步机制
javascript
ohyeah15 小时前
深入理解 JavaScript 数组:从创建到遍历的完整指南
前端·javascript
一室易安15 小时前
模仿elementUI 中Carousel 走马灯卡片模式 type=“card“ 的自定义轮播组件 图片之间有宽度
前端·javascript·elementui
在下胡三汉15 小时前
创建轻量级 3D 资产 - Three.js 中的 GLTF 案例
开发语言·javascript·3d
脸大是真的好~15 小时前
黑马JAVAWeb -Vue工程化 - Element Plus- 表格-分页条-中文语言包-对话框-Form表单
前端·javascript·vue.js