bug 记录 - JavaScript 处理 Number 类型超过 16 位,精度丢失问题

在JavaScript中处理超过16位的数字时遇到了精度丢失问题,导致数据不准确。原因是Number类型能安全表示的数据范围有限。解决方法包括将后端字段类型改为String,或者在前端接收数据时转换类型,以及使用BigInt。由于BigInt的兼容性问题,此项目选择了在axios实例中用正则转换id属性的类型。
摘要由CSDN通过智能技术生成

发现问题

在一个管理端项目中,调用编辑接口对列表内容进行更新。
列表内容一直未被更新,与后端对比如入参发现了问题:
  • 我通过接口接收到的列表数据其中一条的 id 为 1564882714015404000。因此,此条数据进行编辑时,入参传入的主键 id 为 1564882714015404000。
  • 实际上,我看到的数据是在 Preview(预览) 中展示的内容,也就是经过了 JS 反序列化的内容。而在 Response(响应) 中,发现此条数据的 id 为 1564882714015404033。

原因

  • Number 类型的数据是 64 位双精度,能够安全表示的数据范围为 -253 ~ 253 , 即最大安全值为 9007199254740992,在我的项目中,后端传递的数据明显超出这个范围,造成了精度丢失,只保证了前 16 位的精度,16 位之后的数据,只用 0 表示。

解决方法

  • 第一种:后端将此字段类型修改为 String 类型
  • 第二种:前端在接收到响应数据时,反序列化之前,将此字段类型修改为 String 类型
    • 此次我用到的就是这种解决方式,新封装一个 axios 实例,专门用来解决这种精度丢失的问题,在创建实例时,使用正则对 id 属性进行类型的转换
	// 创建 axios 实例
	const transformResponse = function (res) {
	    // id 超过16位, 精度丢失,解决
	    res = res.replace(/\"id\":(\d+)/g, '"id":"$1"')
	    return JSON.parse(res)
	}
	const serviceTransform = axios.create({
	    transformResponse
	});
  • 第三种:JavaScript 新数据类型 BigInt
    • 因此方法兼容性不符合当前项目,故放弃使用,后续再研究
      在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值