一、链判断运算符?.
当我们读取一个对象内部比较深层的属性的时候,往往需要判断一下,属性的上层对象是否存在,以前的写法会是下面这种判断方式:
const  firstName = message.body.user.firstName || 'default';
const firstName = (message
  && message.body
  && message.body.user
  && message.body.user.firstName) || 'default';
但是这种写法需要层层判断对象是否存在,很是麻烦。而使用链判断运算符?.,简化后的写法如下:
const  firstName = message?.body?.user?.firstName || 'default';
?表示判断左侧的对象是否存在,如果存在则继续进行后面点.的读取的操作。如果左侧的对象是null或undefined,则不再往下读取,直接返回undefined。
三种写法
obj?.prop // 对象属性是否存在obj?.[expr] // 同上func?.(...args) // 函数或对象方法是否存在
对于对象的属性和方法都可以使用链判断运算符进行读取。注意该运算符是?和.构成的整体?.,?表示判断左侧的对象是否存在,.表示继续向下读取对象的属性或方法或者进行方法的调用。
如上的后两种写法,通过方括号读取属性和进行方法调用的时候,我们可能习惯性的会只写一个?进行判断,这里需要注意一下哈。
注意
避免过度使用,不要用于已确定存在的对象
链判断运算符的核心作用是 “处理可能不存在的对象 / 属性”,如果对象或属性是明确存在的(如自己定义的普通对象、框架提供的必选参数),则不需要进行链判断,过度使用?.会增加代码冗余。 如下是一个错误示例:
const obj = { name: '张三' };
const name = obj?.name; 
不能用于左侧赋值
?.仅支持 “读取属性 / 调用方法”,不允许用于赋值语句的左侧。这是因为链判断的核心是 “安全读取”,而赋值需要明确的目标对象,若左侧对象不存在,赋值行为本身就是无效的。如下是一个错误示例:
message?.body?.user?.firstName = '张三';
二、Null判断运算符
读取对象属性时,如果某个属性的值是null或undefined,也就是不存在或者未指定初始值的情况,有时需要为它们指定默认值。
以前的做法是通过||短路运算符指定默认值,当左侧的计算值为false的时候,则会读取||右侧的值。但是属性的值如果为空字符串或false或0,都会被转为false值,此时默认值都会生效。但这不是我们所期望的,有的时候我们就是想将值设置为空字符串或false或为0啊。这个时候就可以使用Null判断运算符进行处理。
Null判断运算符??的行为类似短路运算符||,但是只有运算符左侧的值为null或undefined时,才会返回右侧的值,这正是我们期望的设置默认值的情况。
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判断运算符??结合使用是比较常用的方式。前者进行属性的判断和读取,当读取不到值的时候,则通过后者进行默认值的设置。
const headerText = response.settings?.headerText ?? 'Hello, world!';
const animationDuration = response.settings?.animationDuration ?? 300;
const showSplashScreen = response.settings?.showSplashScreen ?? true;
如上response.settings对象上可能不存在.headerText、.animationDuration、.showSplashScreen三个配置项属性,因此先通过?.进行判断,并且分别为三个配置项通过??设置了默认值,这样的读取方式才更为安全。
转自https://juejin.cn/post/7563877908073283599
该文章在 2025/11/3 15:32:00 编辑过