JavaScript记录:由运算符优先级导致的bug

记录:由运算符优先级导致的bug

错误代码以及问题现象

组件日期格式始终显示为 YYYY-MM-DD HH:mm:ss,即使已显式传入 format 参数

jsx 复制代码
<DatePicker 
  format={format ?? showTime ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'}
/>

原因分析

运算符优先级混淆

JavaScript 运算符优先级表(部分):

运算符 优先级 结合性
?? (空值合并) 5 从左到右
?: (三元运算) 4 从右到左

实际执行逻辑:

js 复制代码
// 等效于
(format ?? showTime) ? '...HH:mm:ss' : '...YYYY-MM-DD'

format 存在值时:

  1. ?? 先执行返回非空值
  2. 将非空值转换为布尔值进行三元运算
  3. 任何真值都会触发选择时间格式

解决方案

正确写法

jsx 复制代码
// ✅ 正确使用括号明确优先级
<DatePicker
  format={format ?? (showTime ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD')}
/>

执行逻辑分解

  1. 优先处理三元表达式:

    js 复制代码
    const defaultFormat = showTime ? '...HH:mm:ss' : '...YYYY-MM-DD';
  2. 执行空值合并运算:

    js 复制代码
    finalFormat = format ?? defaultFormat;

验证示例

测试用例 原代码结果 修正后结果
format="YYYY/MM/DD" HH:mm:ss 格式 YYYY/MM/DD
format=null, showTime=true HH:mm:ss 格式 HH:mm:ss 格式
format=undefined, showTime=false HH:mm:ss 格式 YYYY-MM-DD

最佳实践

  1. 括号优先原则:混合使用逻辑运算符时显式使用括号

  2. 分步处理 :对复杂逻辑进行分解

    jsx 复制代码
    const getDefaultFormat = () => 
      showTime ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD';
    
    <DatePicker format={format ?? getDefaultFormat()} />
  3. 类型守卫 :严格判断空值

    js 复制代码
    const finalFormat = typeof format === 'string' ? format : defaultFormat;

关键点:当 ???: 混合使用时,永远显式使用括号明确优先级关系。

相关推荐
偶像你挑的噻3 分钟前
2.Qt-基础核心以及信号与槽
开发语言·qt
用户479492835691511 分钟前
JavaScript 今天30 岁了,但连自己的名字都不属于自己
javascript
potato_may13 分钟前
CC++ 内存管理 —— 程序的“五脏六腑”在哪里?
c语言·开发语言·数据结构·c++·内存·内存管理
饕餮怪程序猿21 分钟前
A*算法(C++实现)
开发语言·c++·算法
用户479492835691525 分钟前
Vite8来啦,告别 esbuild + Rollup,Vite 8 统一用 Rolldown 了
前端·javascript·vite
观音山保我别报错42 分钟前
列表,元组,字典
开发语言·python
**蓝桉**1 小时前
数组的执行原理,java程序的执行原理
java·开发语言
草字1 小时前
uniapp 悬浮按钮支持可拖拽。可移动。
前端·javascript·uni-app
一位搞嵌入式的 genius1 小时前
Vue实例挂载:从原理到项目实践的全维度解析
前端·javascript·vue.js·前端框架
waeng_luo1 小时前
[鸿蒙2025领航者闯关] 表单验证与用户输入处理最佳实践
开发语言·前端·鸿蒙·鸿蒙2025领航者闯关·鸿蒙6实战·开发者年度总结