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

news/2024/11/20 0:25:59/

使用 ?? 重新定义逻辑以获得更严格、更安全的 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' }

http://www.ppmy.cn/news/1273540.html

相关文章

【STM32】STM32学习笔记-EXTI外部中断(11)

00. 目录 文章目录 00. 目录01. 中断系统02. 中断执行流程03. STM32中断04. NVIC基本结构05. NVIC优先级分组06. EXTI简介07. EXTI基本结构08. AFIO复用IO口09. EXTI框图10. 计数器模块11. 旋转编码器简介12. 附录 01. 中断系统 中断:在主程序运行过程中&#xff0…

87 GB 模型种子,GPT-4 缩小版,超越ChatGPT3.5,多平台在线体验

瞬间爆火的Mixtral 8x7B 大家好,我是老章 最近风头最盛的大模型当属Mistral AI 发布的Mixtral 8x7B了,火爆程度压过Google的Gemini。 缘起是MistralAI二话不说,直接在其推特账号上甩出了一个87GB的种子 随后Mixtral公布了模型的一些细节&am…

05 Rust 结构体

结构体 Rust 中的结构体(Struct)与元组(Tuple)都可以将若干个类型不一定相同的数据捆绑在一起形成整体,但结构体的每个成员和其本身都有一个名字,这样访问它成员的时候就不用记住下标了。 元组常用于非定…

C# 命令行参数解析库示例

写在前面 在日常开发中,我们经常会用到命令行参数,比如cmd下的各种指令;还有C#的控制台类型的项目,在默认入口Main函数中,那个args参数,就是有系统传入到程序进程的命令行参数;在传入的参数相对…

【华为OD】依据用户输入的单词前缀,从已输入的英文语句中联想出用户想输入的单词,按字典序输出联想到的单词序列

题目描述主管期望你来实现英文输入法单词联想功能需求如下:依据用户输入的单词前缀,从已输入的英文语句中联想出用户想输入的单词,按字典序输出联想到的单词序列,如果联想不到,请输出用户输入的单词前缀注意1.英文单词联想时,区分大小写2.缩略形式如"dont",判定…

阿里云|人工智能(AI)技术解决方案

函数计算部署Stable Diffusion AI绘画技术解决方案 通过函数计算快速部署Stable Diffusion模型为用户提供快速通过文字生成图片的能力。该方案通过函数计算快速搭建了AIGC的能力,无需管理服务器等基础设施,专注模型的能力即可。该方案具有高效免运维、弹…

深度学习中框架和库的区别是什么。

问题描述:深度学习中框架和库的区别是什么。 问题解决: 框架(Framework): 定义: 一个深度学习框架是一个完整的编程体系结构,它提供了一整套工具和库,用于简化和加速深度学习模型的…

设计模式 简单工厂 工厂方法模式 抽象工厂模式 Spring 工厂 BeanFactory 解析

工厂模式介绍 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。它是创建型模式。 简单工厂 简单工厂模式是指由一个工厂对象决定创建出哪一种产品类的实例, 但它不属于GOF 23种设计模式 简单工厂适用于工厂类负责创建的对象较少的场景,…