都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三个配置项属性,因此先通过?.进行判断,并且分别为三个配置项通过??设置了默认值,这样的读取方式才更为安全。

最后

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

相关推荐
程序猿阿伟11 分钟前
《TypeScript中Protobuf到运行时类型安全的转换指南》
javascript·安全·typescript
前端小菜袅35 分钟前
PC端原样显示移动端页面方案
开发语言·前端·javascript·postcss·px-to-viewport·移动端适配pc端
Highcharts.js37 分钟前
如何使用Highcharts SVG渲染器?
开发语言·javascript·python·svg·highcharts·渲染器
爱问问题的小李1 小时前
ue 动态 Key 导致组件无限重置与 API 重复提交
前端·javascript·vue.js
码云数智-大飞1 小时前
从回调地狱到Promise:JavaScript异步编程的演进之路
开发语言·javascript·ecmascript
子兮曰1 小时前
深入Vue 3响应式系统:为什么嵌套对象修改后界面不更新?
前端·javascript·vue.js
Daniel李华10 小时前
echarts使用案例
android·javascript·echarts
北原_春希10 小时前
如何在Vue3项目中引入并使用Echarts图表
前端·javascript·echarts
JY-HPS10 小时前
echarts天气折线图
javascript·vue.js·echarts
尽意啊10 小时前
echarts树图动态添加子节点
前端·javascript·echarts