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

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

|| 和 ?? 的基本区别

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

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

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

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

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

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

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

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

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

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

|| 和 ?? 的应用场景

  1. 使用 || 处理假值

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

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

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

  2. 使用 ?? 处理空值

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

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

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

常见的误区和潜在问题

  1. || 带来的潜在问题

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

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

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

  2. ?? 也有误用的可能

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

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

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

?? 和 || 的性能差异

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

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

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

最佳实践

  1. ?? 和 || 的组合使用

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

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

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

  2. 使用 ?? 处理空值

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

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

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

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

总结

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

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

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

相关推荐
广州华水科技8 分钟前
北斗形变监测传感器在大坝安全监测中的应用与优势分析
前端
孔令飞15 分钟前
如何学习Go
前端
HUIBUR科技19 分钟前
AI 中枢,面向企业场景构建的 AI 智能体
前端·数据库·人工智能
怕浪猫26 分钟前
给AI配一台电脑,开源版Muse来了,OpenMuse赶紧去二次开发吧
javascript·面试·github
随便写个软件36 分钟前
【新版本】EasyExplorer资源管理器 3.12.0——地址栏重要更新
运维·服务器·前端·everything·资源管理器
Jack N38 分钟前
【Strapi 系列之二】Collection / Single / Component 怎么选?Strapi 字段大全一篇讲透
前端·javascript·strapi
hiahiahia1231 小时前
Agent Tool 执行失败怎么办
服务器·前端
Java后端的Ai之路1 小时前
09-React组件生命周期
前端·react.js·前端框架
IT_陈寒1 小时前
SpringBoot开发实战:从入门到精通
前端·人工智能·后端
乘风gg1 小时前
一个人一个月合并 2500 PRs 的秘密是什么?
前端·ai编程·claude