我正在参加「掘金·启航计划」
前言
前端的同学基本都遇到过,关于js精度丢失的问题;
比如:
后端给前端返回一个数字类型的id,
但是,
前端对这个id不做任何处理,直接使用到下一个给后端请求的时候,
接口报错了,
后端一查,说,你前端id给传错了,然后前端一看,果然是给传错了,
但是自己又没有做什么,怎么拿的就怎么给后端了。问题出在哪呢?
最后,才知道是因为 :
后端给的数字太大超过-9007199254740991 (-(2^53-1))
到9007199254740991(2^53-1)
之间的整数,前端js这块就会自动四舍五入,导致精度丢失。
再比如:
前端要进行大数字之间的运算,也会精度丢失。
可转成字符串
让后端把传过来的id转成字符串;
我司后端当时说他转成字符串了,
但是我这边拿着热乎的数据,检测了类型,是数字非字符串,当然精度依旧会丢失。
最后,
我让他直接简单粗暴加个双引号,我这边检测类型才是字符串,
也不知道为啥,是后端转的有问题还是什么原因。
当然,拿到字符串的id,再传给后端是没有问题的,精度就不会丢失。
问题
前端大数字之间的运算,精度丢失问题无法解决;
BigInt
因为number的基本类型不能超过2^53,不然就会精度丢失,
为了解决这个限制,在ECMAScript标准中出现了BigInt;
什么是?
BigInt可以表示任意大的整数;
创建
- 直接BigInt去创建;
BigInt(value)
- 后面加个n就可;
当然,此方式可以成功解决前端大数字之间运算的问题;
前端直接把热乎的id转成字符串也会精度丢失,但配合BigInt解决了此问题
有次,我是拿到后端给的number类型的id,明明拿着热乎的数据,直接String,转成字符串时,就已经精度丢失了;
于是,我用了第一种方式,让后端给我传过来时,就加双引号转成字符;
第二种方式就是我这边用了BigInt, 本来我以为我这边拿着热乎的id直接Sting一下, 然后传给后端,发现不行,精度也是丢失了,于是就这样:String(BigInt(result));
String配合BigInt,
就可以,解决精度丢失并顺利转成字符传给后端的问题;
结尾
上面,是我的项目中遇到跟后端合作时,前端数据丢失的问题;
我是把后端Number类型的id通过String和BigInt转成字符串传给后端;
但是,咱们就技术而言,不论其他:(平常肯定都是推给后端,让后端转去),
如果后端要求给他传过去的id类型是Number呢,各位大佬可否知道,前端有没有什么好的方式解决呢?