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 或 "")而错误地替换有效值。

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

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

相关推荐
Pedantic1 小时前
SwiftUI 手势层级(Gesture Hierarchy)详解
前端
飘尘1 小时前
前端转型全栈(Java后端)的快速上手指引
前端·后端·全栈
一颗烂土豆1 小时前
Meshopt 压缩深度解析,为什么它比 Draco 更快
前端·javascript·webgl
浏览器工程师2 小时前
AI Agent 接浏览器任务,先别让它一路点到底
前端·后端
雨季mo浅忆2 小时前
VSCode自动格式化三要素
前端
爱勇宝3 小时前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员
kyriewen4 小时前
同事每天催我 Code Review,我写了个脚本让 AI 替我 review PR——现在他反过来催 AI 了
前端·javascript·ai编程
user20585561518136 小时前
Windows 项目安装时报 `node-sass` 错误,如何快速处理
前端
LiaCode6 小时前
Redis 在生产项目的使用
前端·后端