it编程 > 编程语言 > Javascript

JavaScript双问号操作符(??)详解及如何解决使用||时因类型转换带来的问题

8人参与 2025-04-24 Javascript

前言

在现代javascript开发中,处理变量默认值是一个常见但容易引发bug的操作。很多开发者可能都遇到过这样的问题:使用||设置默认值时,意外覆盖了0、''等合法值。这时候,es2020引入的双问号操作符(??)就能完美解决这类问题。本文将带您全面掌握这个操作符的使用场景和高级技巧。

一、双问号操作符??的基础用法

1、传统方式的痛点

const count = 0;
const result = count || 10; // 得到10,但0可能是有效值

使用||时,会把所有假值 (falsy values)视为无效值,包括:0、''、false、nan、null、undefined。这在处理数字表单、开关状态等场景时会引发问题。

以上述案例来说,我想要count被赋值的情况下就使用count的值,要是没有被赋值就使用默认值10,但是当count被初始化并赋值为0的时候,逻辑或操作符||依然会认为是无效值,并将result赋值为10,这显然和我预期的结果相悖。这是因为javascript是一门弱类型语言,会进行强制类型转换。

2、双问号操作符??的精确判断

同样还是这个例子:

const count = 0;
const result = count ?? 10; // 得到0,完美保留有效值

此时result的结果就是10,因为??操作符只对null和undefined这两个原始值进行判断,其他假值都会被保留。这种特性使其特别适合处理以下场景:

3、双问号操作符??与逻辑或操作符||的对比

特性?? 操作符 || 操作符
触发条件

仅 null/undefined

所有假值
适用场景精准空值判断快速默认值设置
处理 0 和 ''保留有效值覆盖为默认值
处理 false保留布尔值覆盖为默认值

二、复杂场景下的空值处理

1、深层嵌套对象的默认值

结合可选链操作符(?.),可以安全地处理多层嵌套对象的属性访问。

const config = {
  api: {
    v1: {
      endpoint: ''
    }
  }
};

// 传统写法(需要逐层判断)
const endpoint = config.api?.v1?.endpoint || 'default';

// 使用??的改进写法
const endpoint = config.api?.v1?.endpoint ?? 'default';

2、函数参数的默认值陷阱

当函数参数需要接收布尔值时,使用??可以避免意外覆盖用户传入的false值。

function createpost(data) {
  // 错误写法:会覆盖有效布尔值
  const ispublic = data.ispublic || true;
  
  // 正确写法:仅处理null/undefined
  const ispublic = data.ispublic ?? true;
}

3、多条件回退策略

通过链式使用??,可以实现多层级的配置回退机制,这种模式在读取环境变量时特别实用。

const theme = userconfig.theme 
  ?? systemconfig.theme 
  ?? process.env.theme 
  ?? 'light';

三、实战案例解析

1、vue组件中的prop处理

如果disabled接收的值为false,如果使用逻辑或操作符,就会被认为是无效值,从而使用默认的true值。如果使用双问号操作符就可以避免这种情况。

<template>
  <input :disabled="isdisabled" />
</template>

<script>
export default {
  props: {
    disabled: {
      type: boolean,
      default: undefined
    }
  },
  computed: {
    isdisabled() {
      return this.disabled ?? true;
    }
  }
}
</script>

2、表单验证

就算你不允许用户输入空格,起码要允许用户输入0和引号吧?如果使用逻辑或操作符,根本无法通过表单验证,使用双问号操作符就可以避免这种情况。

function validateform(formdata) {
  const errors = [];
  
  if (formdata.username?.trim() ?? false) {
    errors.push('用户名不能为空');
  }
  
  if (formdata.age ?? false) {
    errors.push('年龄必须填写');
  }
  
  return errors;
}

四、双问号操作符的性能优势

实际测试显示,??在性能上与||基本持平,但在处理复杂对象时更具优势。这是因为双问号操作符只检查null和undefined,比||操作符的类型转换操作更高效。

当然,这部分差异很小,更多的作用是展示开发者的思维能力。

// 测试环境:chrome 112,100万次运算
console.time('||');
for (let i = 0; i < 1000000; i++) null || 10;
console.timeend('||'); // 2.1ms

console.time('??');
for (let i = 0; i < 1000000; i++) null ?? 10;
console.timeend('??'); // 1.8ms

五、结语

 双问号操作符(??)这个看似简单的语法糖,实则蕴含着提升代码健壮性的强大能力。在实际项目中,建议结合typescript的严格空值检查,构建更可靠的类型安全体系。

到此这篇关于javascript双问号操作符(??)详解及如何解决使用||时因类型转换带来的问题的文章就介绍到这了,更多相关js双问号操作符及||类型转换问题内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

JavaScript中实现Sleep功能及其应用的几种方法

04-24

JavaScript 获取 URL 中参数值的方法详解(最新整理)

04-24

一篇文章详细讲解JavaScript中的this(普通函数、箭头函数、 函数运用)

04-24

纯JS实现监控本地文件变化

04-24

JavaScript中if、else if、else和switch的语法、用法及注意事项

04-24

VS Code中搭建JavaScript运行环境超详细过程

04-24

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论