1:双问操作符

1:前言

这是一个大家看了很熟悉又很陌生的一个运算操作符,有用过吗?它有着什么样的深层含义呢?和我们熟悉的 || 操作符又有什么区别?带着这些问题我们开始探究它究竟在做些什么。

2:深入理解 JavaScript 中的空值合并运算符 ?? 与逻辑或运算符

JavaScript 中, ?? 是"空值合并运算符" (Nullish Coalescing Operator) ,而 || 是逻辑或运算符。虽然这两个运算符都用于提供默认值,但它们在处理空值的方式上有显著区别。

2.1: 空值合并运算符 ??

?? 运算符返回其左侧操作数,若该操作数为 nullundefined,则返回右侧操作数。它只在遇到这两种"空值"时才会返回右侧的值。

示例:

js 复制代码
let a = null
let b = 'Hello'

console.log(a ?? b) // 输出: "Hello"

let c = undefined
let d = 'World'

console.log(c ?? d) // 输出: "World"

let e = 0
let f = 'Default'

2.2.:逻辑或运算符 ||

|| 运算符返回其左侧操作数,若该操作数为假值(如 false、0、""、null、undefined 或 NaN),则返回右侧操作数。

示例:

js 复制代码
let g = null
let h = 'Hello'

console.log(g || h) // 输出: "Hello"

let i = 0
let j = 'Default'

console.log(i || j) // 输出: "Default"

2.3:解决什么痛点

假值混乱,我们实际中使用 || 运算符会有一些不期望的结果出现,有的时候我们只要 null 与 undefined 判假即可。

2.4:运算优先级问题

以下是 JavaScript 运算符的优先级表,按优先级从高到低排列。优先级高的运算符会先于优先级低的运算符执行。

优先级 运算符 描述
1 () 括号,强制优先级
2 . 成员访问
2 [] 数组元素访问
2 new 创建实例
2 ++ -- 自增自减(前置)
3 ++ -- 自增自减(后置)
4 ! ~ - + typeof 一元运算符
5 ** 幂运算符
6 * / % 乘法、除法、取余
7 + - 加法、减法
8 << >> >>> 位移运算符
9 < <= > >= 比较运算符
10 == != === !== 相等与不相等
11 & 按位与
12 ^ 按位异或
13 ` `
14 && 逻辑与
15 `
16 ?? 空值合并运算符
17 ?: 三元运算符
18 = += -= *= /= 赋值运算符
19 yield 生成器的 yield
20 in 会员运算符
20 instanceof 实例运算符
21 , 逗号运算符

注意事项

  • 运算符优先级 :优先级高的运算符会先于优先级低的运算符执行。例如,*/ 的优先级高于 +-
  • 括号 :使用括号 () 可以强制改变运算顺序。
  • 结合性:运算符的结合性决定了在优先级相同的情况下,运算符的计算顺序(例如,从左到右或从右到左)。

3:深层含义与区别

3.1:处理的值:

?? 仅关注 nullundefined|| 关注所有假值。

3.2:使用场景:

使用 ?? 时,通常希望提供一个默认值,仅在变量未定义或为 null 时使用。

使用 || 时,通常希望处理所有可能的假值情况。

4:应用实例

4.1:配置对象

在处理配置对象时,可能会有一些默认值需要设置。使用 ?? 可以确保我们只在缺少必要配置时才使用默认值

js 复制代码
// 获取对应的配置
function getConfig(config) {
  const defaultConfig = {
    host: 'localhost',
    port: 3000,
    useHttps: false
  }
  return {
    host: config.host ?? defaultConfig.host,
    port: config.port ?? defaultConfig.port,
    useHttps: config.useHttps ?? defaultConfig.useHttps
  }
}

// 默认配置
const userConfig = { port: 8080, useHttps: undefined }

// 需处理的配置
const finalConfig = getConfig(userConfig)

console.log(finalConfig)
// 输出: { host: "localhost", port: 8080, useHttps: false }

在这个例子中,useHttps 被设置为 false,因为用户没有提供有效的值。

4.2:用户输入处理

在处理用户输入时,可能会有多种输入类型。使用 ??|| 可以帮助我们更好地管理这些输入。

js 复制代码
// 处理输出
function processInput(input) {
  const defaultInput = 'Default Input'
  // 使用 ?? 确保处理 null 和 undefined
  const finalInput = input ?? defaultInput
  // 使用 || 处理其他假值
  return finalInput || 'Fallback Input'
}

console.log(processInput(null)) // 输出: "Default Input"
console.log(processInput(undefined)) // 输出: "Default Input"
console.log(processInput(0)) // 输出: "Fallback Input"
console.log(processInput('')) // 输出: "Fallback Input"
console.log(processInput('Valid Input')) // 输出: "Valid Input"

在这个例子中,input 为 null 或 undefined 时,返回默认输入;而当 input 为 0 或空字符串时,则返回备用输入。

5:结论

?? 运算符提供了更精确的控制,避免因假值(如 0 或 "")而错误地替换有效值。

|| 运算符则适合处理所有假值的情况。

通过上述示例和分析,希望你能更深入地理解 ??|| 运算符的使用场景及其区别。如果你还有其他更巧妙的使用案例,请与我分享!

相关推荐
阿伟来咯~21 分钟前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端26 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱29 分钟前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai38 分钟前
uniapp
前端·javascript·vue.js·uni-app
也无晴也无风雨39 分钟前
在JS中, 0 == [0] 吗
开发语言·javascript
bysking2 小时前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
独行soc2 小时前
#渗透测试#SRC漏洞挖掘#深入挖掘XSS漏洞02之测试流程
web安全·面试·渗透测试·xss·漏洞挖掘·1024程序员节
王哲晓2 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
fg_4112 小时前
无网络安装ionic和运行
前端·npm
理想不理想v2 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试