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

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

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

相关推荐
天天向上10249 分钟前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
趣多多代言人10 分钟前
从零开始手写嵌入式实时操作系统
开发语言·arm开发·单片机·嵌入式硬件·面试·职场和发展·嵌入式
芬兰y25 分钟前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁31 分钟前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry32 分钟前
Fetch 笔记
前端·javascript
拾光拾趣录33 分钟前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟34 分钟前
vue3,你看setup设计详解,也是个人才
前端
Lefan38 分钟前
一文了解什么是Dart
前端·flutter·dart
Patrick_Wilson43 分钟前
青苔漫染待客迟
前端·设计模式·架构
vvilkim1 小时前
Nuxt.js 全面测试指南:从单元测试到E2E测试
开发语言·javascript·ecmascript