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

使用 ?? 重新定义逻辑以获得更严格、更安全的 JavaScript 默认值

使用 ?? 重新定义逻辑以获得更严格、更安全的 JavaScript 默认值

JavaScript 中的 ?? 运算符称为 nullish 合并运算符。该运算符接受任一侧的操作数,并且仅当左侧操作数为空值时才返回右侧操作数。这个运算符绝对是一个较新的运算符,它是在 ES2020 期间引入 JavaScript 的。

falsy 和 nullish 是相同的吗

如果在布尔表达式中求值时将值强制为 false ,则该值被视为 falsy 值。在这方面,以下值被认为是 falsy 值:

null - 空值
undefined - 未被赋值
false - boolean类型的一个值
0 - 数字0
-0 - 数字0的负数
"" - 空字符
NaN - 非数字

那么,JavaScript 中什么被认为是 nullish 呢?。JavaScript 中的除了 null 或 undefined 的值之外的都是 nullish。

在实际操作该运算符之前,我们应该了解短路运算符的工作原理。

短路运算符

短路运算符基本上是 逻辑与 ( &&) 和 逻辑或 ( || )运算符。它们用于执行简洁的条件逻辑。

&& 运算符

语法:

expression1 && expression2
  • 如果表达式 1 为假并且根本不计算表达式 2,则返回表达式 1

  • 如果表达式 1 为真(除 falsy 值以外的任何值),则返回表达式 2

看一下这个示例

// 返回表达式1
const number = 0 && 100
console.log(number) // 0
// 因为0是falsy值,因此不需要计算表达式2,直接返回表达式1(也就是0)// 返回表达式2
const heroes = 'IronMan' && 'CaptainAmerica'
console.log(heroes) // CaptainAmerica
// 表达式1是一个非空字符,因此直接返回表达式2(也就是 CaptainAmerica)

|| 运算符

语法:

expression1 || expression2
  • 如果表达式 1 为真,则返回表达式 1
  • 如果表达式 1 为假则返回表达式 2

就这么简单。

看一下这个示例:

// 返回表达式1
const heroes = 'IronMan' || 'CaptainAmerica'
console.log(heroes) // 'IronMan'
// 表达式1是一个非空字符,为 truthy 值,直接返回表达式1// 返回表达式2
const number = 0 || 100
console.log(number) //100
// 0 是 falsy 值,直接返回表达2

?? 运算符

除了 && 和 || 之外,还存在另一个运算符,称为空合并运算符。而且,该运算符就像逻辑运算符的特例,其操作与 || 运算符类似。

由于|| 当左侧操作数为 falsy 时,该运算符返回右侧表达式。而空合并 ?? 运算符仅在左侧操作数为 null 或 undefined 时才返回右侧表达式。所以,?? 运算符比现有的 || 运算符更加严格。

语法:

expression1 ?? expression2

仅当 表达式1 为 null 或 undefined 时,?? 运算符才返回表达式2 。同时,如果表达式1是 nullish 值以外的任何值,则返回表达式1。

// 示例1
const number = 0 ?? 100
console.log(number) // 0
// 0 为非 nullish// 示例2
let fruit = ''
let veggie = 'Carrot'
const basket = fruit ?? veggie
console.log(basket) // ''
// fruit 虽然是空字符,但是是 falsy 值而非 nullish// 示例3
let halves = 'fullPortion' / 2
let full = 1
const portion = halves ?? full
console.log(portion) // NaN// 示例4
let hero1
let hero2 = 'CaptainAmerica'
const heroes = hero1 ?? hero2
console.log(heroes) // 'CaptainAmerica'
// hero1为undefined,是 nullish值

?? 运算符的设计方式使其不能直接与 && 和 || 一起使用,而需要使用括号:

null || undefined ?? 'hi' // SyntaxError: missing ) after argument list(null || undefined) ?? 'hi' //'hi'

为什么要使用短路运算符

当我们看到一些不熟悉的语法可以工作时,这个问题就会出现。难道我们不能坚持使用经典的 if else 语法来量化表达式吗?是的,我们可以,但是不行。让我解释一下为什么会这样。只要我们使用纯 JavaScript,我们就可以使用 if else 条件。但当涉及到使用像 ReactJs 这样的前端 UI 库时,不可能在 JSX 结构中嵌入“if 语句”。在这方面,我们应该只使用使用逻辑运算符的表达式。

这不是唯一的用例。但是这些短路运算符(包括空合并运算符)避免了用单行代码不必要地执行表达式。

我们可以使用短路运算符构建更复杂的逻辑,如下所示:

const gameConfig1 = { playerName: 'John',score: 22500,highScore: 35000,
}
const gameConfig2 = { playerName: undefined, score: undefined,highScore: undefined
}
function getPlayerInfo( player ){const { playerName, score, highScore } = playerconst currentPlayerName= playerName ?? 'Guest'const currentPlayerScore = ( score >= 100 && score ) || 'No scores yet'const currentPlayerHighScore = highScore ?? 'No high scores yet'return { currentPlayerName, currentPlayerScore , currentPlayerHighScore }
}
const player1 = getPlayerInfo( gameConfig1 ) // { name: John, score: 22500, highScore: 35000 }
const player2 = getPlayerInfo( gameConfig2 ) // { name: 'Guest', score: 'No scores yet', highScore: 'No high scores yet' }

相关文章:

使用 ?? 重新定义逻辑以获得更严格、更安全的 JavaScript 默认值

使用 ?? 重新定义逻辑以获得更严格、更安全的 JavaScript 默认值 JavaScript 中的 ?? 运算符称为 nullish 合并运算符。该运算符接受任一侧的操作数,并且仅当左侧操作数为空值时才返回右侧操作数。这个运算符绝对是一个较新的运算符,它是在 ES2020 …...

Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7

问题描述:Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7 最近在学习如何将YOLO部署在手机端,出现了许多错误,下面这个错误是手机和电脑连结之后,点击run之后出现的错误。 解决办法:将JDK版本将为…...

Python Django Suit:构建现代化的Django后台管理

概要 Django Suit是一款为Django后台管理提供现代、优雅界面的第三方应用,它致力于提升Django开发者的管理体验。本文将深入介绍Django Suit的安装、配置和高级功能,提供详实的示例代码,帮助大家更好地使用和定制Django后台管理界面。 安装与…...

电子学会C/C++编程等级考试2021年09月(六级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:双端队列 定义一个双端队列,进队操作与普通队列一样,从队尾进入。出队操作既可以从队头,也可以从队尾。编程实现这个数据结构。 时间限制:1000 内存限制:65535输入 第一行输入一个整数t,代表测试数据的组数。 每组数据的…...

SpringBoot 源码解析

前言 本文只是纯源码分析文章,阅读者需要有Spring或者SpringBoot使用经验。 SpringBoot 源码解析 SpringBoot 源码解析1:环境搭建 SpringBoot 源码解析2:启动流程1 SpringBoot 源码解析3:启动流程2 SpringBoot 源码解析4&#…...

dockerfile---创建镜像

dockerfile创建镜像:创建自定义镜像。 包扩配置文件的创建,挂载点,对外暴露的端口。设置环境变量。 docker镜像的方式: 1、基于官方源进行创建 根据官方提供的镜像源,创建镜像,然后拉起容器。是一个白板&#xff0c…...

Raspberry PI + Codesys + EtherCAT步进驱动ECR60 Motion功能测试

原文连接&#xff1a;Raspberry PI Codesys EtherCAT步进驱动ECR60 Motion功能测试 – 个人资料收集 (rtplc.com) <div class"post_info_wrapper "> <p class"has-drop-cap">运动控制功能是codesys及EtherCAT通讯的重要功能&am…...

03 Temporal 详细介绍

前言 在后端开发中&#xff0c;大家是否有遇到如下类型的开发场景 需要处理较多的异步事件需要的外部服务可靠性较低需要记录保存某个对象的复杂状态 在以往的开发过程中&#xff0c;可能更多的直接使用数据库、定时任务、消息队列等作为基础&#xff0c;来解决上面的问题。然…...

【算法】【动规】乘积为正数的最长子数组长度

跳转汇总链接 &#x1f449;&#x1f517;算法题汇总链接 1.1 乘积为正数的最长子数组长度 &#x1f517;题目链接 给你一个整数数组 nums &#xff0c;请你求出乘积为正数的最长子数组的长度。 一个数组的子数组是由原数组中零个或者更多个连续数字组成的数组。 请你返回乘积…...

Kubernetes实战(十四)-k8s高可用集群扩容master节点

1 单master集群和多master节点集群方案 1.1 单Master集群 k8s 集群是由一组运行 k8s 的节点组成的&#xff0c;节点可以是物理机、虚拟机或者云服务器。k8s 集群中的节点分为两种角色&#xff1a;master 和 node。 master 节点&#xff1a;master 节点负责控制和管理整个集群…...

Spring之容器:IOC(1)

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…...

【.Net 6.0--通用帮助类--ConvertHelper】

前言 类型转换帮助类&#xff0c;包含下表中的方法&#xff1a; 方法名方法解释ObjToIntobject转intObjToMoneyobject转doubleObjToStringobject转stringObjToDecimalobject转decimalObjToDateobject转datetimeObjToDateSplitYMDobject转datetime&#xff08;yyyy-MM-dd&…...

【加解密】报文签名与加解密,MD5,RSA,AES使用案例(基于 Java)

需要考虑哪些问题&#xff1f; 在进行报文传输时&#xff0c;有两个问题需要考虑&#xff1a; 消息防篡改加密报文 定义消息结构 为了方便后面使用&#xff0c;这里定义消息结构&#xff1a; public static class Message {public String data; //消息public String sign;…...

新建vue3项目

三种方法 一. 第一种方式 1、操作步骤&#xff1a; 创建项目目录 vue create 项目名称选择配置方式 ? Please pick a preset: #选择一个配置 Default &#xff08;[Vue 3] babel, eslint&#xff09;Default &#xff08;[Vue 2] babel, eslint&#xff09;Manually select …...

出现 Error:Unable to access jarfile xxxx\target\nacos-server.jar 解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 执行Nacos中的startup.cmd的时候出现闪退,于是在该脚本的最后一行添加pause,查看因为什么原因闪退 出现的bug如下所示:Error:Unable to access jarfile xxxx\target\nacos-server.jar 截图如下所示: 查看内部文件夹,…...

记录一次API报文替换点滴

1. 需求 各位盆友在日常开发中&#xff0c;有没有遇到上游接口突然不合作了&#xff0c;临时需要切换其他接口的情况&#xff1f;这不巧了&#xff0c;博主团队近期遇到了&#xff0c;又尴尬又忐忑。 尴尬的是临时通知不合作了&#xff0c;事前没有任何提醒&#xff1b; 忐忑…...

PMP项目管理 - 沟通管理

系列文章目录 PMP项目管理 - 质量管理 PMP项目管理 - 采购管理 PMP项目管理 - 资源管理 PMP项目管理 - 风险管理 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in…...

fckeditor编辑器改造示例:增加PRE,CODE控件

查看专栏目录 Network 灰鸽宝典专栏主要关注服务器的配置&#xff0c;前后端开发环境的配置&#xff0c;编辑器的配置&#xff0c;网络服务的配置&#xff0c;网络命令的应用与配置&#xff0c;windows常见问题的解决等。 文章目录 修改方法&#xff1a;1&#xff09;修改fckco…...

风速预测(五)基于Pytorch的EMD-CNN-LSTM模型

目录 前言 1 风速数据EMD分解与可视化 1.1 导入数据 1.2 EMD分解 2 数据集制作与预处理 2.1 先划分数据集&#xff0c;按照8&#xff1a;2划分训练集和测试集 2.2 设置滑动窗口大小为96&#xff0c;制作数据集 3 基于Pytorch的EMD-CNN-LSTM模型预测 3.1 数据加载&…...

单元测试二(理论)-云计算2023.12-云南农业大学

文章目录 一、单选题1、三次握手、四次挥手发生在网络模型的哪一层上&#xff1f;2、互联网Internet的拓扑结构是什么&#xff1f;3、以下哪一种网络设备是工作在网络层的&#xff1f;4、以下哪种关于分组交换网络的说法是错误的&#xff1f;5、以下哪种协议是在TCP/IP模型中的…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...