当前位置: 首页 > article >正文

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

目录

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

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

1、传统方式的痛点

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

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

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

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

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

3、多条件回退策略

三、实战案例解析

1、Vue组件中的Prop处理

2、表单验证

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

五、结语


        作者:watermelo37

        CSDN万粉博主、华为云云享专家、阿里云专家博主、腾讯云、支付宝合作作者,全平台博客昵称watermelo37。

        一个假装是giser的coder,做不只专注于业务逻辑的前端工程师,Java、Docker、Python、LLM均有涉猎。

---------------------------------------------------------------------

温柔地对待温柔的人,包容的三观就是最大的温柔。

---------------------------------------------------------------------

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这两个原始值进行判断,其他假值都会被保留。这种特性使其特别适合处理以下场景:

  • 表单输入值(允许0或空字符串)
  • 布尔类型配置项
  • 数字类型参数(允许0)

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/undefinedconst 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.1msconsole.time('??');
for (let i = 0; i < 1000000; i++) null ?? 10;
console.timeEnd('??'); // 1.8ms

五、结语

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

        只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

        其他热门文章,请关注:

        极致的灵活度满足工程美学:用Vue Flow绘制一个完美流程图

        你真的会使用Vue3的onMounted钩子函数吗?Vue3中onMounted的用法详解

        DeepSeek:全栈开发者视角下的AI革命者

        通过array.filter()实现数组的数据筛选、数据清洗和链式调用

        通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能

        TreeSize:免费的磁盘清理与管理神器,解决C盘爆满的燃眉之急

        通过MongoDB Atlas 实现语义搜索与 RAG——迈向AI的搜索机制

        深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解

        el-table实现动态数据的实时排序,一篇文章讲清楚elementui的表格排序功能

        MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver

        JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、DOM操作等

        高效工作流:用Mermaid绘制你的专属流程图;如何在Vue3中导入mermaid绘制流程图

        Dockerfile全面指南:从基础到进阶,掌握容器化构建的核心工具

        在线编程实现!如何在Java后端通过DockerClient操作Docker生成python环境

        干货含源码!如何用Java后端操作Docker(命令行篇)

相关文章:

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

目录 JavaScript双问号操作符&#xff08;??&#xff09;详解&#xff0c;解决使用||时因类型转换带来的问题 一、双问号操作符??的基础用法 1、传统方式的痛点 2、双问号操作符??的精确判断 3、双问号操作符??与逻辑或操作符||的对比 二、复杂场景下的空值处理 …...

蓝桥杯 web 展开你的扇子(css3)

普通答案&#xff1a; #box:hover #item1{transform: rotate(-60deg); } #box:hover #item2{transform: rotate(-50deg); } #box:hover #item3{transform: rotate(-40deg); } #box:hover #item4{transform: rotate(-30deg); } #box:hover #item5{transform: rotate(-20deg); }…...

聚焦楼宇自控:优化建筑性能,引领智能化管控与舒适环境

在当今建筑行业蓬勃发展的浪潮中&#xff0c;人们对建筑的要求早已超越了传统的遮风避雨功能&#xff0c;而是更加注重建筑性能的优化、智能化的管控以及舒适环境的营造。楼宇自控系统作为现代建筑技术的核心力量&#xff0c;正凭借其卓越的功能和先进的技术&#xff0c;在这几…...

前端视频流技术深度解析

一、视频流技术体系架构 1.1 现代视频流技术栈 1.1.1 核心协议对比 协议传输方式延迟适用场景浏览器支持HLSHTTP分片6-30s点播、直播回看全平台DASHHTTP动态适配3-15s多码率自适应Chrome/FirefoxWebRTCP2P/UDP<500ms实时通信、直播现代浏览器RTMPTCP长连接1-3s传统直播推…...

k8s核心资源对象一(入门到精通)

本文将深入探讨Kubernetes中的核心资源对象&#xff0c;包括Pod、Deployment、Service、Ingress、ConfigMap和Secret&#xff0c;详细解析其概念、功能以及实际应用场景&#xff0c;帮助读者全面掌握这些关键组件的使用方法。 一、pod 1 pod概念 k8s最小调度单元&#xff0c;…...

Ubuntu16.04配置远程连接

配置静态IP Ubuntu16.04 修改超管账户默认密码 # 修改root账户默认密码 sudo passwd Ubuntu16.04安装SSH # 安装ssh服务&#xff1a; sudo apt-get install ssh# 启动SSH服务&#xff1a; sudo /etc/init.d/ssh start # 开机自启 sudo systemctl enable ssh# 如无法连接&…...

基于springboot微信小程序课堂签到及提问系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 随着信息时代的来临&#xff0c;过去的课堂签到及提问管理方式的缺点逐渐暴露&#xff0c;本次对过去的课堂签到及提问管理方式的缺点进行分析&#xff0c;采取计算机方式构建基于微信小程序的课堂签到及提问系统。本文通过阅读相关文献&#xff0c;研究国内外相关技术&a…...

互联网三高-高性能之JVM调优

1 运行时数据区 JVM运行时数据区是Java虚拟机管理的内存核心模块&#xff0c;主要分为线程共享和线程私有两部分。 &#xff08;1&#xff09;线程私有 ① 程序计数器&#xff1a;存储当前线程执行字节码指令的地址&#xff0c;用于分支、循环、异常处理等流程控制‌ ② 虚拟机…...

数据操作语言

一、DML的核心操作类型 1.添加数据(INSERT) (1)手动插入:逐行插入数据,适用于少量数据。 INSERT INTO 表名 (字段1, 字段2) VALUES (值1, 值2);(2)批量导入:通过外部文件导入数据,适用于大数据场景...

智谛达科技:以创新为翼,翱翔AI人形机器人蓝海

在科技创新的浩瀚星空中,智谛达科技集团犹如一颗璀璨的明星,以其独特的创新光芒,照亮了AI人形机器人的广阔蓝海。这家在AI领域深耕多年的企业,始终秉持着创新为翼的发展理念,不断突破技术瓶颈,拓展应用场景,以卓越的实力和前瞻性的思维,引领着人形机器人行业的未来发展。 智谛达…...

封装可拖动弹窗(vue jquery引入到html的版本)

vue cli上简单的功能&#xff0c;在js上太难弄了&#xff0c;这个弹窗功能时常用到&#xff0c;保存起来备用吧 备注&#xff1a;deepseek这个人工智障写一堆有问题的我&#xff0c;还老服务器繁忙 效果图&#xff1a; html代码&#xff1a; <div class"modal-mask&qu…...

【LeetCode77】组合

题目描述 给定区间 [1, n] 和一个整数 k&#xff0c;需要返回所有可能的 k 个数的组合。 思路 算法选择&#xff1a;回溯算法 回溯算法是一种试探性搜索方法&#xff0c;非常适合用来解决组合问题。基本思想是&#xff1a; 从数字 1 开始&#xff0c;逐步构建组合。当当前组…...

【技术报告】GPT-4o 原生图像生成的应用与分析

【技术报告】GPT-4o 原生图像生成的应用与分析 1. GPT-4o 原生图像生成简介1.1 文本渲染能力1.2 多轮对话迭代1.3 指令遵循能力1.4 上下文学习能力1.5 跨模态知识调用1.6 逼真画质与多元风格1.7 局限性与安全性 2. GPT-4o 技术报告2.1 引言2.2 安全挑战、评估与缓解措施2.2.1 安…...

初阶数据结构(3)顺序表

Hello~,欢迎大家来到我的博客进行学习&#xff01; 目录 1.线性表2.顺序表2.1 概念与结构2.2 分类2.2.1 静态顺序表2.2.2 动态顺序表 2.3 动态顺序表的实现初始化尾插头插尾删头删查找指定位置之前插入数据删除指定位置的数据销毁 1.线性表 首先我们需要知道的是&#xff0c;…...

Visual Studio 中使用 Clang 作为 C/C++ 编译器时,设置优化选项方法

在 Visual Studio 中使用 Clang 作为 C/C 编译器时&#xff0c;可以通过以下方法设置优化选项&#xff1a; 方法 1&#xff1a;通过项目属性设置&#xff08;推荐&#xff09; 右键项目 → 属性 配置属性 → C/C → 优化 优化&#xff1a;选择优化级别 /O0 - 禁用优化&#x…...

设计模式简述(七)原型模式

原型模式 描述基本使用 使用场景 描述 基于已有对象&#xff0c;利用JDK的Cloneable接口&#xff0c;生成一个新的对象。 常用于需要同时创建多个对象的场景 默认的clone是浅拷贝&#xff0c;如果要实现深拷贝需自行处理 可以在clone方法中手动拷贝数组成员或者其他引用类型成…...

Linux中查看占用端口号的进程信息的方法

在 Linux 中查看占用 ** 端口&#xff08;eg:1717&#xff09;**的进程号&#xff08;PID&#xff09;&#xff0c;可以通过以下命令实现&#xff1a; 方法 1&#xff1a;使用 netstat 命令 sudo netstat -tulnp | grep :1717参数解释&#xff1a; -t&#xff1a;查看 TCP 端口…...

谷歌发布网络安全AI新模型Sec-Gemini v1

谷歌近日宣布推出实验性AI模型Sec-Gemini v1&#xff0c;旨在通过人工智能技术革新网络安全防御体系。该模型由Sec-Gemini团队成员Elie Burzstein和Marianna Tishchenko共同研发&#xff0c;旨在帮助网络安全人员应对日益复杂的网络威胁。 攻防不对称的破局之道 Sec-Gemini团队…...

【学Rust写CAD】35 alpha_mul_256(alpha256.rs补充方法)

源码 // Calculates (value * alpha256) / 255 in range [0,256], // for [0,255] value and [0,256] alpha256. pub fn alpha_mul_256(self,value: u32) -> Alpha256 {let prod value * self.0;Alpha256((prod (prod >> 8)) >> 8) }代码分析 这个函数 alph…...

嵌入式工程师多线程编程(三)裸机编程、RTOS、Linux及多线程编程的全面对比

以下是裸机编程、RTOS、Linux及多线程编程的全面对比解析&#xff0c;结合技术特性和应用场景进行深度分析&#xff1a; 一、架构与调度机制对比 维度裸机编程RTOSLinux任务调度无调度器&#xff08;轮询/前后台系统&#xff09;抢占式优先级调度&#xff08;硬实时&#xff0…...

Meta LLaMA 4:对抗 GPT-4o 与 Claude 的开源王牌

2025 年 4 月&#xff0c;Meta 正式发布了 LLaMA 4 系列的首批两款模型。 这两款模型模型分别是&#xff1a;LLaMA 4 Scout 与 LLaMA 4 Maverick&#xff0c;均采用了 专家混合架构&#xff08;Mixture-of-Experts, MoE&#xff09;。 据 Meta 表示&#xff0c;这是首次有 …...

企业级 ClickHouse Docker 离线部署实践指南20250407

企业级 ClickHouse Docker 离线部署实践指南 引言 在数据分析与日志处理日益重要的今天&#xff0c;ClickHouse 凭借其高性能、列式存储架构&#xff0c;成为企业在大数据分析中的首选引擎之一。本文基于一位金融行业从业者在离线网络环境中部署 ClickHouse 的真实实践过程&a…...

STM32看门狗应用实战:独立看门狗与窗口看门狗深度解析(下) | 零基础入门STM32第九十五步

主题内容教学目的/扩展视频看门狗什么是看门狗&#xff0c;原理分析&#xff0c;启动喂狗方法&#xff0c;读标志位。熟悉在程序里用看门狗。 师从洋桃电子&#xff0c;杜洋老师 &#x1f4d1;文章目录 一、看门狗应用架构分析1.1 系统监控流程图1.2 双看门狗应用场景对比 二、…...

DeepSeek-MLA

MLA 结构 需要缓存 KV 向量共用的压缩隐特征K 向量多头共享的带位置编码的向量 为什么带有位置信息的 Q 向量来自于隐特征向量&#xff0c;而带有位置的 K 向量来自于 H 向量且共享呢&#xff1f; 最好的方法肯定是从H向量直接计算并且不共享&#xff0c;但是会大大增加显存使…...

pyTorch-迁移学习-学习率衰减-四种天气图片多分类问题

目录 1.导包 2.加载数据、拼接训练、测试数据的文件夹路径 3.数据预处理 3.1 transforms.Compose数据转化 3.2分类存储的图片数据创建dataloader torchvision.datasets.ImageFolder torch.utils.data.DataLoader 4.加载预训练好的模型(迁移学习) 4.1固定、修改预训练…...

基于大模型的GCSE预测与治疗优化系统技术方案

目录 技术方案文档:基于大模型的GCSE预测与治疗优化系统1. 数据预处理模块功能:整合多模态数据(EEG、MRI、临床指标等),标准化并生成训练集。伪代码流程图2. 大模型架构(Transformer-GNN混合模型)功能:联合建模时序信号(EEG)与空间结构(脑网络)。伪代码流程图3. 术…...

vscode Colipot 编程助手

1、登录到colipot&#xff0c;以github账号&#xff0c;关联登录 点击【continue】按钮&#xff0c;继续。 点击【打开Visual Studio Code】&#xff0c;回到vscode中。 2、问一下11? 可以看出&#xff0c;很聪明&#xff0c;一下子就算出来了。 3、帮我们写一个文件&#xf…...

1、window 下SDL 下载使用, 测试环境搭建

1. SDL3下载 官网&#xff1a; https://www.libsdl.org/ 点击SDL Releases 或者 SDL GItHub 进入github下载&#xff1a; 因为自己在windows下使用的mingw,所以下载mingw版的&#xff0c;也可以 下载源码自己编译。 2. 项目搭建 这里使用的时mingw vsocde cmake, 可以使…...

OpenGL学习笔记(模型材质、光照贴图)

目录 光照与材质光照贴图漫反射贴图采样镜面光贴图 GitHub主页&#xff1a;https://github.com/sdpyy OpenGL学习仓库:https://github.com/sdpyy1/CppLearn/tree/main/OpenGLtree/main/OpenGL):https://github.com/sdpyy1/CppLearn/tree/main/OpenGL 光照与材质 在现实世界里&…...

【MySQL】常用SQL--持续更新ing

一、配置信息类 1.查看版本 select version; 或 select version(); 2.查看配置 show global variables where variable_name in (basedir,binlog_format,datadir,expire_logs_days,innodb_buffer_pool_size,innodb_log_buffer_size,innodb_log_file_size,innodb_log_files_i…...