跳到主要内容

Number 的存储空间多大?后端发了超过最大安全整数怎么办?

面试速答(30 秒版 TL;DR)

  • JS 的 number 规范上对应 IEEE 754 双精度浮点数,可以按 **64 bit(8 字节)**来理解。
  • number 能精确表示的最大安全整数是 Number.MAX_SAFE_INTEGER (2^53 - 1);超过后会丢精度。
  • 如果后端发来超大整数(ID、订单号等):不要用 number 接,而是用 字符串 传输,前端按需转 BigInt 或全程用字符串。

“存储空间 8 字节”应该怎么回答更严谨?

面试口径可以这么说:

  • 语言规范层面:number 是 IEEE 754 双精度语义,按 64 位理解即可。
  • 引擎实现层面可能有“指针标记/小整数优化”等内部表示,但那是实现细节,不改变 number 的语义边界(尤其是安全整数范围)。

最大安全整数与精度丢失示例

Number.MAX_SAFE_INTEGER; // 9007199254740991

// 超过安全整数后,很多“看似不同”的整数会变成同一个 number
9007199254740991 + 1 === 9007199254740991 + 2; // true

这类问题在“ID/金额/计数”场景很致命,因为你会把两个不同的值当成同一个。


后端发送超大整数的常见正确做法

方案 1:接口层用字符串传输(最推荐)

后端返回:

{"id":"9223372036854775807"}

前端:

const idStr = data.id; // string
const id = BigInt(idStr); // 需要算就转 BigInt

方案 2:如果必须用 JSON 且要保留大整数

  • 约定字段为字符串(同方案 1)
  • 或使用“能保留大整数”的 JSON 解析方案(工程工具层面),但面试更看重你是否理解“标准 JSON 不支持 BigInt、number 会丢精度”

典型题 & 标准答法

Q1:后端发来的 64 位整数(比如 long)能用 JS number 精确表示吗?

不一定。64 位整数上限约 9e18,超过 JS number 的安全整数上限 9e15 左右(2^53 - 19e15),所以很多 64 位整数会丢精度,应该用字符串或 BigInt。

Q2:那用 BigInt 就完美了吗?

  • BigInt 解决的是“整数精度”问题,但不支持小数,且不能直接 JSON 序列化,需要接口约定。

易错点/坑

  • JSON.parse 会把数字解析成 number,大整数会在解析时就丢精度,之后再怎么补救都晚了。
  • 把“ID”当数字处理:会导致去重、比较、Map key 等逻辑出 bug;ID 通常更适合用字符串语义。

速记要点(可背诵)

  • number 按 64 位双精度理解;安全整数上限 2^53 - 1
  • 后端超大整数:字符串传输,前端按需转 BigInt;不要让 JSON 先把它变成 number。