JavaScript 悄悄改掉的那些 JSON 数字
来源:dev.to — 2026-10-23
📋 概述
JSON 只有一种数字类型且不限长度,JS 也只有一种,即 IEEE-754 双精度,整数精度 53 位,超过 9007199254740991 就开始舍入,而且既不报错也不警告。作者列出三种失效模式:大整数被舍入,比如 Discord 雪花 ID、数据库 bigint、Stripe 风格的数字标识,末两位是编出来的;超出范围变成 Infinity,再 stringify 就成了 null,这是一次类型变化而不是精度问题;还有值活下来了但格式被摧毁。他的判断是标识符最危险:价格舍入一眼能看出错,ID 舍入后仍是一个长相合法、却指向空无甚至指向别人的 ID。
🔑 核心要点
- JSON.parse 没有 bug,它只是把无限的数字语法映射进有限类型,并选择静默丢失。
- 往返一次 Infinity 会变成 null,下游拿到的是类型变化,不是数值误差。
- 最该防的是 ID 而不是金额:错的价格显眼,错的 ID 看起来完全正常。
💡 金句
“A rounded price is obviously wrong. A rounded ID is a valid-looking ID that points at nothing, or worse, at something else.”
译:被舍入的价格一眼就是错的;被舍入的 ID 却是一个看起来合法、却指向空无、甚至指向别处的 ID。
← 返回 dev.to 首页