We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
当前, JS 的 JSON 方法均不支持 bigint.
如果想要保持向前兼容, 直接让 JS JSON 支持 bigint 是不行的.
不过, 有一些可插拔的办法, 比如最近刚进入 stage 3 的 https://github.com/tc39/proposal-json-parse-with-source 提案.
该提案的目的之一就是为了解决 bigint 不兼容问题, 官方例子如下:
const tooBigForNumber = BigInt(Number.MAX_SAFE_INTEGER) + 2n; const intToBigInt = (key, val, {source}) => typeof val === "number" && val % 1 === 0 ? BigInt(source) : val; const roundTripped = JSON.parse(String(tooBigForNumber), intToBigInt); tooBigForNumber === roundTripped; // → true const bigIntToRawJSON = (key, val) => typeof val === "bigint" ? JSON.rawJSON(val) : val; const embedded = JSON.stringify({ tooBigForNumber }, bigIntToRawJSON); embedded === '{"tooBigForNumber":9007199254740993}'; // → true
看上去很好, 不过与我们之前的做法略有不兼容的是, 针对 bigint, 我们使用 string, 比如 1n 会被转为 "1".
1n
"1"
不过我们之前还存在的问题是小于 MAX_SAFE_INTEGER 的 bigint, 到底是否需要保留?
我之前的做法是保留. 前后端通过中间层转换. 不过这样需要对类型非常明确, 每次做针对性的转换.
之前考虑过是否要写通用函数, 其实类似 JSON 方法第二个参数. 但是考虑到 "不知道哪些字符串该被转为 bigint", 所以放弃了通用做法, 而是使用中间层做有针对性的显性转换. 做针对性转换的一个好处就是可以区分 1n, 1, "1". 通用转换要不就是无法区分 1n 和 "1", 要不就是无法区分 1n 和 1.
1
如果既要通用, 又要支持区分, 就会像 DynamoDB 一样搞成 {type: "bigint", value: "1"}, {type: "int", value: "1"} 这样.
{type: "bigint", value: "1"}
{type: "int", value: "1"}
我们现在会频繁遇到这个问题主要是因为 UNIX 时间戳, 在数据库中需要是 bigint (因为考虑到不远的 2038 年就会溢出 int), 但 JS 中的 MAX_SAFE_INTEGER 实际会较大, 有时我们会选择 number 来存放 UNIX 时间戳.
2147483647
Math.pow(Math.pow(2, 8), 4) 分两半, 正数占一半
9007199254740991
Math.pow(2, 53)
感觉 int4 就很讲理, 但 JS, 这 53, 就感觉不是那么讲理了.
The text was updated successfully, but these errors were encountered:
No branches or pull requests
当前, JS 的 JSON 方法均不支持 bigint.
json-parse-with-source 提案解决 BigInt JSON 化问题
如果想要保持向前兼容, 直接让 JS JSON 支持 bigint 是不行的.
不过, 有一些可插拔的办法, 比如最近刚进入 stage 3 的 https://github.com/tc39/proposal-json-parse-with-source 提案.
该提案的目的之一就是为了解决 bigint 不兼容问题, 官方例子如下:
看上去很好, 不过与我们之前的做法略有不兼容的是, 针对 bigint, 我们使用 string, 比如
1n
会被转为"1"
.不过我们之前还存在的问题是小于 MAX_SAFE_INTEGER 的 bigint, 到底是否需要保留?
我之前的做法是保留. 前后端通过中间层转换. 不过这样需要对类型非常明确, 每次做针对性的转换.
之前考虑过是否要写通用函数, 其实类似 JSON 方法第二个参数. 但是考虑到 "不知道哪些字符串该被转为 bigint", 所以放弃了通用做法, 而是使用中间层做有针对性的显性转换. 做针对性转换的一个好处就是可以区分
1n
,1
,"1"
. 通用转换要不就是无法区分1n
和"1"
, 要不就是无法区分1n
和1
.如果既要通用, 又要支持区分, 就会像 DynamoDB 一样搞成
{type: "bigint", value: "1"}
,{type: "int", value: "1"}
这样.为什么需要将 BigInt JSON 化
我们现在会频繁遇到这个问题主要是因为 UNIX 时间戳, 在数据库中需要是 bigint (因为考虑到不远的 2038 年就会溢出 int), 但 JS 中的 MAX_SAFE_INTEGER 实际会较大, 有时我们会选择 number 来存放 UNIX 时间戳.
2147483647
Math.pow(Math.pow(2, 8), 4) 分两半, 正数占一半
9007199254740991
Math.pow(2, 53)
感觉 int4 就很讲理, 但 JS, 这 53, 就感觉不是那么讲理了.
The text was updated successfully, but these errors were encountered: