JavaScript 逻辑赋值运算符(=,||=,??=)与可选链运算符(?. ??)

news/2024/7/1 5:20:05

一、 短路运算

短路运算是一种常见的逻辑运算方式,其核心机制是在运算过程中进行一些优化和简化,从而提高计算效率和减少资源消耗。特别是在处理逻辑与(&&)和逻辑或(||)运算时,如果左侧的表达式已经能够确定整个逻辑表达式的结果,那么右侧的表达式将不会被执行,因此任何与其求值产生的相关副作用都不会生效。

二、 逻辑赋值运算符

  • &&=:逻辑与赋值运算符 x &&= y 等价于 x && (x=y):意思是当 x 为真时,x = y。
  • ||=:逻辑或赋值运算符 x ||= y 等价于 x || (x = y):意思是仅在 x 为 false 的时候,x = y。
  • ??=:逻辑空赋值运算符 x ??= y 等价于 x ?? (x = y):意思是仅在 x 为 null 或 undefined 的时候,x = y
//&&=
let a = 1;
a &&= 2;
console.log(a); // 2
//||=
const aa = { duration: 50, title: '' };
aa.duration ||= 10;
console.log(aa.duration);  // 50
aa.title ||= 'title is empty.';
console.log(aa.title);  // "title is empty"
//??=
const a = { duration: 50 };
ac.duration ??= 10;
console.log(ac.duration);  // 50
ac.speed ??= 25;
console.log(ac.speed);  // 25

常见应用

  • 用于条件判断、链式判断以及空指针判断等场景。例如,在判断一个对象是否为空以及其属性是否满足特定条件时,可以使用短路运算来避免空指针异常。
  • 进行复杂的条件判断时,如果某个关键条件不满足(即为假),则后续的条件判断可以省略,从而提高代码执行效率。

使用示例

在日常开发中,像以现一些代码是可以用逻辑赋值运算符代替

// 给data.code为空时,赋值为y
// 示例1
if (!data.code) {
data.code= y
}
// 示例2
data.code? "" : (data.code = y)

可以使用逻辑与替代

data.code ||= y

三、其他常用运算符

1. 空值合并运算符(??)

空值合并运算符(??)是一个逻辑运算符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。
与逻辑或运算符(||)不同,逻辑或运算符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,‘’ 或 0)时。见下面的例子。

const foo = null ?? 'default string';
console.log(foo);
// Expected output: "default string"

const baz = 0 ?? 42;
console.log(baz);
// Expected output: 0

为变更赋默认值
由于 || 是一个布尔逻辑运算符,左侧的操作数会被强制转换成布尔值用于求值。任何假值(0, ‘’, NaN, null, undefined)都不会被返回。这导致如果你使用0,''或NaN作为有效值,就会出现不可预料的后果。

let count = 0;
let text = "";
let qty = count || 42;
let message = text || "hi!";
console.log(qty); // 42,而不是 0
console.log(message); // "hi!",而不是 ""

// An empty string (which is also a falsy value)
let myText = ""; 
let notFalsyText = myText || "Hello world";
console.log(notFalsyText); // Hello world
let preservingFalsy = myText ?? "Hi neighborhood";
console.log(preservingFalsy); // '' (as myText is neither undefined nor null)

2. 可选链运算符(?.)

可选链运算符(?.)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。
?. 运算符的功能类似于 . 链式运算符,不同之处在于,在引用为空 (nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。

let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];
console.log(x); // x 将不会被递增,依旧输出 0

可以结合空值合并运算符设置默认值
空值合并运算符针对 undefined 与 null 这两个值,可选链式运算符(?.) 也是如此。在访问属性可能为 undefined 与 null 的对象时,?.与??结合使用非常有用。

let customer = {
  name: "Carl",
  details: { age: 82 },
};
let customerCity = customer?.city ?? "暗之城";
console.log(customerCity); // “暗之城”

可选链不能用于赋值
需要注意的是时,可选链是不用用于赋值对象的

let object = {};
object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment

3、TypeScript中的非空断言操作符(!)

由于可选链不能用于赋值,所以在没有属性接口或类型定义的情况下,如何给没有明确属性定义的对象赋值呢?

let object=await getObject();
object!.code='A001'

! 是TypeScript中的非空断言操作符。它告诉TypeScript编译器,尽管从静态类型检查的角度来看,code 属性可能是 null 或 undefined,但在实际运行时,你确信它不是。这通常是因为你确信在某个特定的代码执行路径中,该属性已经被正确地初始化了。
使用非空断言操作符需要谨慎,因为它可能会掩盖潜在的错误。如果你断言了一个实际上可能是 null 或 undefined 的值,那么在运行时可能会出现错误。为了避免这种情况,你可能需要在赋值之前添加一些额外的检查。


http://lihuaxi.xjx100.cn/news/2215653.html

相关文章

搭建k8s集群报错unknown command “\u00a0“ for “kubeadm init“

搭建k8s报错unknown command “\u00a0” for “kubeadm init” 网上搜了一下,是因为复制过来的命令前面包含了空格,将复制的命令放到idea可以清楚看到几个命令前面有空格,删除掉就好了,记录一下

【电路笔记】-共基极放大器

共基极放大器 文章目录 共基极放大器1、概述2、等效电路3、电流增益4、输入阻抗5、输出阻抗6、电压增益7、示例:电压、电流和功率增益8、总结1、概述 在本文中,我们将介绍双极晶体管放大器的最后一种拓扑,称为共基极放大器 (CBA)。 下面的图 1 显示了 CBA 的电气图,此处没…

【编程语言】Python平台化为何比Java差?

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…

jumpserver的入门与实践

Jumpserver 是一个开源的堡垒机系统,它基于 Python 编写,使用 Django 框架,提供了审计、认证、授权、资产和会话管理等功能。以下是 Jumpserver 的入门与实践的基本步骤: 入门 了解Jumpserver: 访问 Jumpserver 官网 …

基于SSM+Jsp的列车票务信息管理系统

开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包…

cmake aux_source_directory详解

在 CMake 中,aux_source_directory 命令用于将指定目录中的源文件列表添加到一个变量中。这对于需要自动发现目录中所有源文件的情况非常有用,特别是在构建测试或动态加载模块时。 基本语法 aux_source_directory(dir variable)dir:源文件所…

java技术专家面试指南80问【java学习+面试宝典】(九)

队列和栈是什么,列出它们的区别? 栈和队列两者都被用来预存储数据。java.util.Queue是一个接口,它的实现类在Java并发包中。队列允许先进先出(FIFO)检索元素,但并非总是这样。Deque接口允许从两端检索元素…

JavaScript常见面试题(一)

文章目录 1. JavaScript有哪些数据类型,它们的区别?2.数据类型检测的方式有哪些3. 判断数组的方式有哪些4.null和undefined区别5.typeof null 的结果是什么,为什么?6.intanceof 操作符的实现原理及实现7.为什么0.10.2 ! 0.3&…