当前位置: 首页 > article >正文

#Js篇: 链式判断运算符 ?.和Null判断运算符 ??和逻辑赋值运算符||= = ??=

链式判断运算符 ?.

?.运算符,直接在链式调用的时候判断,左侧的对象是否为null或undefined。如果是的,就不再往下运算,而是返回undefined。

链判断运算符?.有三种写法。

obj?.prop // 对象属性是否存在
obj?.[expr] // 同上
func?.(…args) // 函数或对象方法是否存在
下面是obj?.[expr]用法的一个例子。

let hex = "#C0FFEE".match(/#([A-Z]+)/i)?.[1];

上面例子中,字符串的match()方法,如果没有发现匹配会返回null,如果发现匹配会返回一个数组,?.运算符起到了判断作用。

下面是?.运算符常见形式,以及不使用该运算符时的等价形式。
a?.b
// 等同于
a == null ? undefined : a.b

a?.[x]
// 等同于
a == null ? undefined : a[x]

a?.b()
// 等同于
a == null ? undefined : a.b()

a?.()
// 等同于
a == null ? undefined : a()

Null 判断运算符 ??

读取对象属性的时候,如果某个属性的值是null或undefined,有时候需要为它们指定默认值。常见做法是通过||运算符指定默认值。

第一种弊端 所有的false都会取默认值
const headerText = response.settings.headerText || 'Hello, world!';
const animationDuration = response.settings.animationDuration || 300;
const showSplashScreen = response.settings.showSplashScreen || true;

上面的三行代码都通过||运算符指定默认值,但是这样写是错的。开发者的原意是,只要属性的值为null或undefined,默认值就会生效,但是属性的值如果为空字符串或false或0,默认值也会生效。

只有为null or undefined才会取默认值
const headerText = response.settings.headerText ?? 'Hello, world!';
const animationDuration = response.settings.animationDuration ?? 300;
const showSplashScreen = response.settings.showSplashScreen ?? true;

上面代码中,默认值只有在左侧属性值为null或undefined时,才会生效。


这个运算符的一个目的,就是跟链判断运算符?.配合使用,为null或undefined的值设置默认值。

const animationDuration = response.settings?.animationDuration ?? 300;

上面代码中,如果response.settings是null或undefined,或者response.settings.animationDuration是null或undefined,就会返回默认值300。也就是说,这一行代码包括了两级属性的判断。

??本质上是逻辑运算,它与其他两个逻辑运算符&&和||有一个优先级问题,它们之间的优先级到底孰高孰低。优先级的不同,往往会导致逻辑运算的结果不同。

现在的规则是,如果多个逻辑运算符一起使用,必须用括号表明优先级,否则会报错。

(lhs && middle) ?? rhs;
lhs && (middle ?? rhs);

(lhs ?? middle) && rhs;
lhs ?? (middle && rhs);

(lhs || middle) ?? rhs;
lhs || (middle ?? rhs);

(lhs ?? middle) || rhs;
lhs ?? (middle || rhs);

逻辑赋值运算符 ||=、&&=、??=

// 或赋值运算符
x ||= y
// 等同于
x || (x = y)

// 与赋值运算符
x &&= y
// 等同于
x && (x = y)

// Null 赋值运算符
x ??= y
// 等同于
x ?? (x = y)
// 老的写法
user.id = user.id || 1;

// 新的写法
user.id ||= 1;

http://www.kler.cn/a/415909.html

相关文章:

  • k8s 1.28 二进制安装与部署
  • redis机制详解
  • 蓝桥杯备赛笔记(一)
  • 数组和链表OJ题
  • 多线程+线程池
  • VR云展让企业实现产品的多样展示
  • 领养我的宠物:SpringBoot开发指南
  • Cesium K-means自动聚合点的原理
  • 史陶比尔机器人维修-接口总结
  • Mac启动服务慢问题解决,InetAddress.getLocalHost().getHostAddress()慢问题。
  • 3.24MayBeSomeComputeC
  • 如何通过PHP爬虫模拟表单提交,抓取隐藏数据
  • USB Type-C一线通扩展屏:多场景应用,重塑高效办公与极致娱乐体验
  • 26页PDF | 数据中台能力框架及评估体系解读(限免下载)
  • linux-信号
  • springboot339javaweb的新能源充电系统pf(论文+源码)_kaic
  • nginx同一域名下部署多个项目
  • 【动态规划】股票市场交易策略优化
  • hhdb数据库介绍(10-17)
  • Kylin Server V10 下 Nacos 集群部署
  • KST-3D01型胎儿超声仿真体模、吸声材料以及超声骨密度仪用定量试件介绍
  • 总结UiPath Studio的介绍与安装步骤
  • DETR:End-to-End Object Detection with Transformers
  • Android触摸事件setOnTouchListener用法
  • 各个排序算法基础速通万字介绍
  • STM32--MAP文件