前端那些事儿:?? vs || 在 JavaScript 中的区别

JavaScript 中,我们经常会遇到需要判断值是否为空或者是否为假值的场景。为此,JavaScript 提供了两个非常常见的运算符------||(逻辑或运算符)和 ??(空值合并运算符)。虽然它们在某些情况下看起来非常相似,但实际上它们的行为和适用场景却有很大的不同。了解这两者的区别,能帮助我们更好地书写代码,避免一些潜在的错误。

||?? 的基本区别

  1. ||(逻辑或运算符)

    ||JavaScript 中的逻辑运算符,通常用于两个布尔值之间的运算。但是,在实际使用中,|| 被广泛用于判断一个值是否为假值 ,即判断一个值是否为 false0NaN、空字符串 ""nullundefined,只要是这些值中的任何一个,|| 就会返回后面的默认值。

    javascript 复制代码
    let value = "";  // 空字符串
    let result = value || "默认值";  // 返回 "默认值"

    这就像是你在一家餐厅里,点了一个空盘子(""),服务员看不下去,直接给你上了默认的美味佳肴------"默认值"。即使你不饿,他也一定要喂你吃。

    在这个例子中,由于 value 是空字符串 "",这是一个假值,因此 || 运算符会返回默认值 "默认值"

  2. ??(空值合并运算符)

    ?? 是一种相对较新的运算符,它仅用于判断值是否为 nullundefined,如果是其中之一,则返回右侧的默认值;如果不是 nullundefined,则返回原值。和 || 不同,?? 不会把其他假值(如 0false、空字符串等)视为空值。

    javascript 复制代码
    let value = "";  // 空字符串
    let result = value ?? "默认值";  // 返回 ""

    就像你去餐厅点了一个空盘子(""),但服务员觉得你没事,不会再给你额外的"默认值"。他认为,你没饿到需要"默认值"来救急。

    在这里,value 是一个空字符串 "",而不是 nullundefined,所以 ?? 不会替换它,result 的值仍然是 ""

||?? 的应用场景

  1. 使用 || 处理假值

    || 用于判断是否为假值 ,并提供一个默认值。当我们需要确保某个变量有一个"有效"的值时,|| 是一种非常常见的解决方案。

    javascript 复制代码
    let userInput = "";  // 用户输入为空字符串
    let name = userInput || "默认用户名";  // 返回 "默认用户名"

    如果 userInput 是空字符串 "",这时就会使用默认值 "默认用户名"

  2. 使用 ?? 处理空值

    如果我们只关心 空值nullundefined),而不希望其他假值(如 0、空字符串等)被替换成默认值,那么 ?? 是更好的选择。

    javascript 复制代码
    let userInput = "";  // 用户输入为空字符串
    let name = userInput || "默认用户名";  // 返回 "默认用户名"

    在这个例子中,userInput 是一个空字符串,它不是 nullundefined,所以 ?? 运算符不会返回默认值,而是保持原值 ""

常见的误区和潜在问题

  1. || 带来的潜在问题

    虽然 || 运算符可以很方便地处理假值,但是它有时会带来一些意想不到的结果,特别是当我们传递的值本身就是一个有效的假值 (如 0"")时:

    javascript 复制代码
    let price = 0;  // 商品价格是 0
    let discount = price || 100;  // 结果会变成 100,而不是 0

    在上面的例子中,price0,这本来是一个有效的价格,但由于 0 是一个假值,|| 会将其替换为默认值 100,这显然不是我们期望的行为。

  2. ?? 也有误用的可能

    虽然 ?? 更为精确,但它仍然有潜在的误用场景,特别是在我们希望处理所有假值的场景中:

    javascript 复制代码
    let userInput = 0;  // 用户输入的是 0
    let name = userInput ?? "默认用户名";  // 返回 0,而不是 "默认用户名"

    在这个例子中,userInput0,这是一个有效的输入值,不应该用默认值 "默认用户名" 替换。如果使用 ??0 将不会被替换,所以 name 的值就是 0,而不是默认的 "默认用户名"

??|| 的性能差异

虽然两者看起来相似,但它们的底层实现不同,可能会对性能产生影响。具体来说:

  • || 运算符:每次遇到一个假值时,它就会继续判断下一个值,直到找到一个真值。
  • ?? 运算符 :仅当左侧的值为 nullundefined 时才会判断右侧的值。

理论上,?? 的判断条件更严格,因此在某些情况下,使用 ?? 的性能可能会稍好一些。然而,在实际应用中,两者的性能差异微乎其微,通常不需要过多关注。
5.

最佳实践

  1. ??|| 的组合使用

    有时候,我们可能需要先检查某个值是否为 nullundefined,如果是,再处理其他假值。这时,可以结合 ??|| 来实现更复杂的逻辑:

    javascript 复制代码
    let userInput = 0;  // 用户输入的是 0
    let price = userInput ?? 100 || 200;  // 如果 userInput 是 null 或 undefined,返回 100,否则返回 0

    这里我们先通过 ?? 确保只有在 userInputnullundefined 时才替换为 100,然后通过 || 处理假值,确保在 0 的情况下仍然返回 0

  2. 使用 ?? 处理空值

    当我们只关心 nullundefined 时,使用 ?? 是更合适的选择:

    javascript 复制代码
    let foo = null;
    let bar = foo ?? "默认值";  // 返回 "默认值"
  3. 使用 || 处理假值

    如果我们需要处理所有类型的假值,并提供一个默认值,使用 || 是合适的选择:

    javascript 复制代码
    let foo = 0;
    let bar = foo || "默认值";  // 返回 "默认值"

总结

  • || 用于处理任何假值 (包括 0false、空字符串、nullundefined),返回默认值。
  • ?? 仅在值为 nullundefined 时返回默认值,其他假值不会触发默认值。

在实际开发中,我们需要根据不同的需求来选择使用哪个运算符。如果我们只关心空值(nullundefined),就应该使用 ??。而如果我们需要处理其他假值,|| 会是更好的选择。

希望这篇博客能帮助你更好地理解 ??|| 运算符的区别,避免潜在的错误,编写出更加高效和可读的 JavaScript 代码!

相关推荐
活宝小娜1 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点1 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow1 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o1 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic2 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā2 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
沉默璇年3 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder3 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_882727573 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
SoaringHeart4 小时前
Flutter进阶:基于 MLKit 的 OCR 文字识别
前端·flutter