空值合并运算符(??)及其使用场景

空值合并操作符(??) 是一个逻辑操作符,当左侧的操作数为 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

示例场景

使用空值合并操作符

在这个例子中,我们使用空值合并操作符为常量提供默认值,保证常量不为 null 或者 undefined。

const nullValue = null;  
const emptyText = ""; // 空字符串,是一个假值,Boolean("") === false  
const someNumber = 42;  const valA = nullValue ?? "valA 的默认值";  
const valB = emptyText ?? "valB 的默认值";  
const valC = someNumber ?? 0;  console.log(valA); // "valA 的默认值"  
console.log(valB); // ""(空字符串虽然是假值,但不是 null 或者 undefined)  
console.log(valC); // 42

为变量赋默认值

以前,如果想为一个变量赋默认值,通常的做法是使用逻辑或操作符(||):

let foo;  //  foo is never assigned any value so it is still undefined  
let someDummyText = foo || 'Hello!';

然而,由于 || 是一个布尔逻辑运算符,左侧的操作数会被强制转换成布尔值用于求值。任何假值(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!",而不是 ""

空值合并操作符可以避免这种陷阱,其只在第一个操作数为null 或 undefined 时(而不是其它假值)返回第二个操作数:

let myText = ''; // An empty string (which is also a falsy value)  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)

短路

与 OR 和 AND 逻辑操作符相似,当左表达式不为 null 或 undefined 时,不会对右表达式进行求值。

function A() { console.log('函数 A 被调用了'); return undefined; }  
function B() { console.log('函数 B 被调用了'); return false; }  
function C() { console.log('函数 C 被调用了'); return "foo"; }  console.log( A() ?? C() );  
// 依次打印 "函数 A 被调用了"、"函数 C 被调用了"、"foo"  
// A() 返回了 undefined,所以操作符两边的表达式都被执行了  console.log( B() ?? C() );  
// 依次打印 "函数 B 被调用了"、"false"  
// B() 返回了 false(既不是 null 也不是 undefined)  
// 所以右侧表达式没有被执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/114637.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DataGridView的下拉DataGridViewComboBoxColumn的数据绑定问题

DataGridView的下拉DataGridViewComboBoxColumn的数据绑定问题 需求:左边这列固定x行,右边显示下拉,并且赋上默认值 public void Set(){// 添加需要固定显示的行数dataGridView1.Rows.Add("早班";dataGridView1.Rows.Add("中…

小团队之间有哪些好用免费的多人协同办公软件

在小团队协作中,选择适合的多人协同办公软件是提高工作效率和团队协作的重要一环。幸运的是,市场上有许多大多数功能都免费的多人协同办公软件,为小团队提供了强大的协作功能和便捷的工作环境。 在本文中,我将根据自己多年的在线…

[C++] C++入门

☃️个人主页:fighting小泽 🌸作者简介:目前正在学习C和Linux 🌼博客专栏:C入门 🏵️欢迎关注:评论👊🏻点赞👍🏻留言💪🏻 …

Cesium Vue(六)— 材质(Material)

1. 设置entity材质 添加棋盘纹理材质 // 棋盘纹理 let material new Cesium.CheckerboardMaterialProperty({ evenColor: Cesium.Color.RED, oddColor: Cesium.Color.YELLOW, repeat: new Cesium.Cartesian2(2, 2), });添加条纹纹理材质 // 条纹纹理 let material new Cesium…

Java利用反射和读取xml实现迷你容器

由于需要框架能实现多态,达到控制反转解耦。所以容器还是需要的,容器的存在可以简化对象获取工作,但是容器也不是万能的。合理使用即可,Spring对我来说太庞大了,用不着,为此给框架写一个迷你版容器。 容器…

Qt中Json的操作

在 Json的两种格式中介绍了Json的格式以及应用场景。由于这种数据格式与语言无关,下面介绍一下Json在Qt中的使用。 从Qt 5.0开始提供了对Json的支持,我们可以直接使用Qt提供的Json类进行数据的组织和解析。相关的类常用的主要有四个,具体如下: Json类介绍 QJsonDocument |…

OpenAI接口开发指南

OpenAI主要API OpenAI Api 官方地址为:https://platform.openai.com/docs/api-reference,常用的 OpenAI Api 接口总共分为 4 类:对话类、私有化模型训练类、通用类、图片 & 音频类,其中对话类与私有化模型训练类是最常用的。…

【vSphere 8 自签名证书】企业 CA 签名证书替换 vSphere Machine SSL 证书Ⅰ—— 生成 CSR

目录 替换拓扑图证书关系示意图说明 & 关联博文 1. 默认证书截图2. 使用certificate-manager生成CSR2.1 创建存放CSR的目录2.2 记录PNID和IP2.3 生成CSR2.4 验证CSR 参考资料 替换拓扑图 证书关系示意图 默认情况下,VMCA 与 Machine SSL的关系是 本系列博文要…

UE5--物体卡片与材质入门

参考资料: 《Unreal Engine5 入门到精通》--左央 虚幻引擎5.2文档:https://docs.unrealengine.com/5.2/zh-CN/ 前言: 跟着左央老师的《Unreal Engine5 入门到精通》学习制作AI版胡闹厨房,把学习过程与学习到的东西归纳总结起来。 …

Ruby 之 csv 文件读写

csv 文件写入 require csvtitle ["col1", "col2"] contents [["row11", "row12"], ["row21", "row22"]]csv1 CSV.open("test1.csv", "wb") do |csv|# write file titlecsv << titl…

【网络协议】聊聊网关 NAT机制

再宿舍的时候&#xff0c;其实只能通过局域网进行处理&#xff0c;但是如果接入互联网&#xff0c;一般是配置路由器当然还有网关。 MAC头和IP头的细节 一旦配置了IP地址和网关&#xff0c;就可以制定目标地址进行访问。 MAC头主要信息目标和源MAC地址&#xff0c;以及协议类…

OpenCV显示中文(python)

OpenCV添加文字的方法putText(…)&#xff0c;添加英文是没有问题的&#xff0c;但如果你要添加中文就会出现“&#xff1f;&#xff1f;&#xff1f;”的乱码&#xff0c;需要特殊处理一下。 下文提供封装好的&#xff08;代码&#xff09;方法&#xff0c;供OpenCV添加中文使…

hive substr用法

hive substr用法 substr(string A, int start, int len) 其中start大於0&#xff0c;表示從前往后取數據&#xff0c;start小於0&#xff0c;表示從後往前取數據 if(matnr like 0000000000%, substring(matnr, -8), matnr) matnr,取倒數8個數 if(matnr like 0000000000%, subs…

【试题040】多个逻辑或例题2

1.题目&#xff1a;设int n0;&#xff0c;执行表达式n ||(n-1) ||(n0)||(n1)||(n2)后n的值是 &#xff1f; 2.代码解析&#xff1a; 逻辑或 || 运算符是一个短路运算符&#xff0c;它从左到右依次计算表达式&#xff0c;如果遇到一个为真&#xff08;非零&#xff09;的值&am…

javaweb中的servlet注解

2023.10.22 在web.xml文件中进行servlet信息的配置&#xff0c;显然开发效率比较低&#xff0c;每一个都需要配置一下。 在web.xml文件中的配置中&#xff0c;很少被修改的那部分&#xff0c;可以直接写在java类中。 Servlet3.0版本之后&#xff0c;推出了各种Servlet基于注解式…

kotlin修饰符const的含义

一. const属性简介 在 Kotlin 中&#xff0c;const 修饰符用于声明常量&#xff0c;常量的值在编译时就确定了&#xff0c;并且可以在编译时被嵌入到代码中 二. 使用const属性 companion object 中定义的属性和方法可以在类的实例上直接访问&#xff0c;就像 Java 中的静态变量…

uCOSIII实时操作系统 十 事件标志组

目录 事件标志组&#xff1a; 事件标志组API函数&#xff1a; 创建事件标志组&#xff1a; 等待事件标志组&#xff1a; 向事件标志组发送标志&#xff1a; 事件标志组实验&#xff1a; 事件标志组&#xff1a; 有时候一个任务可能需要和多个事件同步这个时候就需要使用事…

39.克鲁斯卡尔(Kruskal)算法

一言 已知n个顶点&#xff0c;选n-1条最短的边&#xff0c;不可成环。 概述 克鲁斯卡尔&#xff08;Kruskal&#xff09;算法是用来求加权连通图的最小生成树的算法。其基本思想是按照权值从小到大的顺序选择n-1条边&#xff0c;保证这n-1条边不构成回路。 这就要求要首先构…

一百九十一、Flume——Flume配置文件各参数含义(持续完善中)

一、目的 在实际项目的开发过程中&#xff0c;不同Kafka主题的数据规模、数据频率&#xff0c;需要配置不同的Flume参数&#xff0c;而这一切的调试、配置工作&#xff0c;都要建立在对Flume配置文件各参数含义的基础上 二、Flume各参数及其含义 &#xff08;一&#xff09;…

集成学习方法(随机森林和AdaBoost)

释义 集成学习很好的避免了单一学习模型带来的过拟合问题 根据个体学习器的生成方式&#xff0c;目前的集成学习方法大致可分为两大类&#xff1a; Bagging(个体学习器间不存在强依赖关系、可同时生成的并行化方法) 流行版本&#xff1a;随机森林(random forest)Boosting(个体…