前端JS接收后端的Long长整型数据,并且保证不丢失精度的解决思路

前言

前端与后端对接的途中,有时我们会遇到一些奇怪的坑,例如后端传给前端一个Long类型的数据(可能是某张表的id或是某个随机值),但是前端接收后,数据竟然发生了微妙的变化,这背后的底层原理,就是JS语言number数据类型的精度丢失。

原因分析

在提及如何解决之前,我们得先知道前端JS具体是如何丢失精度的。
前端存储数值的类型叫做number,它的数据范围很奇怪(相对于其他语言),安全整数范围是 -(2^53 - 1) 到 2^53 - 1,这就导致它的范围大于后端(例如Java)的int,但是小于后端的Long
而一旦我们传给前端一个超过其范围的数字,JS就会以浮动数(floating point)的方式存储它,其后果就是我们往往发现Long类型的数据,最后一位可能发生变化.

解决思路

常见误区

1.接受异步返回值并以BigInt存储

很容易想到的解决思路,就是获取到异步请求返回值后以BigInt存储,由于BigInt的上限理论上可以无限大,因而不会造成精度损失。
但是这种方式忽略了一个事实,就是我们通过异步请求获取到返回值时,后端的Long已经自动转换成了number类型。即使我们继续将其转化为BigInt,已经造成的精度丢失也无法逆转。
而且,即使我们使用的是TS,定义泛型也依旧不能阻止数值被转换成number.

2.接受异步返回值并以String存储

本质和上面一样,如果后端的json数据是数值类型的,那么异步返回获取到的数据就会自动转换number类型,即使后续转为string也无济于事。

正确思路

后端将Long类型数据以String方式序列化,具体实现通常需要配置对应语言框架的序列化器,以Java的SpringBoot项目为例(其默认序列化器为Jackson),其配置方式如下:

@JsonSerialize(using = LongToStringSerializer.class)
private Long myLongField;

这样我们后端发送的json返回内容就会是以字符串形式被前端接收。
后续处理起来就不用担心精度损失。

<think>好的,用户想了解如何在前端Long类型的数据转换为字符串。首先,我需要确认JavaScript中的数据类型。JavaScript没有明确的Long类型,通常数字都是以双精度浮点数存储的,但可能会有大整数的情况,比如超过Number.MAX_SAFE_INTEGER的情况,这时候可能需要用字符串来处理。 接下来,常见的转换方法有哪些呢?首先想到的是toString()方法,这是最直接的方式。比如,变量后面直接调用toString(),或者使用String()构造函数。例如,let num = 123456789n; num.toString()。这里需要注意,如果数字超过了安全整数范围,可能需要使用BigInt类型,并在后面加n,这时候用toString()转换是有效的。 然后,模板字符串也是一种方法,比如`${num}`,这样可以将变量插入字符串中,自动转换为字符串。这种方法简洁,但可能对于大数需要注意类型是否正确。 另外,JSON.stringify()也可以用来转换,不过这个方法通常用于对象,但单独的数字用的话,可能有点多余,不过确实可行。例如,JSON.stringify(num)会返回字符串形式的数字。 还要考虑大整数的情况,比如当数字超过2^53-1时,JavaScript的Number类型无法精确表示,这时候需要将数字作为字符串传输,避免精度丢失。例如,从后端传过来的Long类型数据,最好以字符串形式传递,前端直接接收字符串即可,不需要转换。如果后端返回的是数值,前端处理时可以用BigInt,然后转字符串。 然后,参考用户提供的引用内容,比如引用[2]中提到处理String类型时,如果不是JSON对象就原样输出字符串。这可能意味着在前端如果接收Long类型的数据,可能需要判断类型,如果不是字符串,就进行转换。例如,使用typeof检查,如果是number,就调用toString()。 另外,用户可能遇到的具体问题是什么?比如,后端返回的Long类型数据前端丢失精度,这时候应该建议后端以字符串格式返回,或者在前端JSON解析时处理成字符串。例如,使用JSON.parse的reviver函数,将特定字段转换为字符串。 还要考虑不同的场景,比如使用axios等库接收数据时,可以配置转换逻辑,或者在数据处理阶段统一处理。如果用户使用的是某些框架,比如React或Vue,可能在状态管理时需要转换类型。 总结可能的转换方法:toString()、String()、模板字符串、JSON.stringify(),以及处理大整数的BigInt转换。同时,建议后端返回字符串以避免精度问题,或者在前端解析时处理。</think>在前端JavaScript中将长整型(long)数据转换为字符串主要有以下几种方法: ### 一、基本转换方法 1. **toString() 方法** 直接调用数值的`toString()`方法: ```javascript const longNumber = 1234567890123456789n; // 注意大整数需要加n后缀 const str = longNumber.toString(); // "1234567890123456789" ``` 2. **String() 构造函数** 使用类型转换函数: ```javascript const num = 9876543210; const str = String(num); // "9876543210" ``` 3. **模板字符串** 通过反引号表达式自动转换: ```javascript const bigIntValue = 9007199254740993n; console.log(`${bigIntValue}`); // "9007199254740993" ``` ### 二、大整数处理 当数值超过$2^{53}-1$(JavaScript安全整数范围)时: ```javascript // 后端返回的JSON数据建议使用字符串格式 const response = '{"id": "9223372036854775807"}'; const data = JSON.parse(response); console.log(data.id); // 直接得到字符串类型的值[^2] ``` ### 三、特殊场景处理 若需要处理数值型JSON响应: ```javascript const jsonString = '{"id": 9223372036854775807}'; const data = JSON.parse(jsonString, (key, value) => { return key === 'id' ? String(value) : value; }); ``` ### 四、最佳实践建议 1. 后端接口设计时,对于超过$2^{53}-1$的整数值应直接返回字符串类型 2. 前端处理大数运算时推荐使用`BigInt`类型: ```javascript const bigNum = BigInt("9223372036854775807"); console.log(bigNum.toString()); // "9223372036854775807" ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值