前言
今天在学习kotlin项目时,发现项目中有一个奇怪的现象。凡是,将ID返回给前端时,都是以String
的类型返回,而不是常见的整形。
将代码研究了很久,不理解这种奇怪的行为,为什么不直接以数字类型传给前端呢?Kotlin小伙伴,告诉我较大数字会在JavaScript的JSON转换时,丢失精度。
问题
当使用Long类型以JSON格式传给前端时,数字会变得不一致(丢失精度)。
// 后端返回的原始数据
{
"id": 113145644503269376
}
// 前端解析到的数据
{
"id": 113145644503269380
}
神奇的事情发生了,id
发生了变化。
原因
在JavaScript中,Number类型有最大和最小的安全整数。
范围如下:
// ES6
Number.MIN_SAFE_INTEGER; // -9007199254740991
Number.MAX_SAFE_INTEGER; // 9007199254740991
在解析序列化的JSON时,如果JSON解析器将它们强制转换为Number类型,那么超出此范围的整数值可能会被破坏。在工作中使用
String
类型代替,是一个可行的解决方案。
我们做两个实验
// 例子一
Number(9007199254740999) // 9007199254741000 超过最大安全整数,转换时,精度丢失。
// 例子二
var x = 9007199254740992;
var y = -x;
x == x + 1; // true
y == y - 1; // true
解决办法
将较大数字类型的ID,以String
类型传递给前端。
总结
在kotlin项目中,ID是使用ID生成器生成的18位整数,但是JavaScript中Number最大的安全整数为16位。生成的ID超过了最大安全数,故在JSON解析时,发生精度丢失。因此,推荐使用String
类型来传递较大整数。
网友评论