如何在JavaScript中序列化64位整数?

6

Datadog追踪API需要将64位整数序列化为JSON数字。

{
  "span_id": 16956440953342013954,
  "trace_id": 13756071592735822010
}

如何使用JavaScript创建包含64位整数的JSON?


1
我认为你需要使用Uint8Array和/或DataView。 - Mister Jojo
1个回答

3
这实际上比看起来更难。
使用 BigInt 数据类型(通过在数字后缀加上 n)可以在 JavaScript 中表示大整数,目前已经得到了相当广泛的支持。
这将使您的对象看起来像这样:
const o = {
  span_id: 16956440953342013954n,
  trace_id: 13756071592735822010n
};

问题出现在JSON序列化中,目前没有支持BigInt对象序列化的方法。而且当涉及到JSON序列化时,你的自定义选项非常有限:
  • 可以与JSON.stringify()一起使用的replacer函数将允许您自定义BigInt对象的序列化行为,但不允许将它们序列化为原始(不带引号)字符串。
  • 出于同样的原因,在BigInt原型上实现toJSON()方法也不起作用。
  • 由于JSON.stringify()似乎不会在内部递归调用自身,涉及将其包装在代理中的解决方案也不起作用。
所以我能找到的唯一选择是(至少部分地)实现自己的JSON序列化机制。
这是一个非常简陋的实现,针对类型为 BigInt 的对象属性调用 toString(),并委托给 JSON.stringify() 处理其他情况:

const o = {
  "span_id": 16956440953342013954n,
  "trace_id": 13756071592735822010n
};

const stringify = (o) => '{'
  + Object.entries(o).reduce((a, [k, v]) => ([
      ...a, 
      `"${k}": ${typeof v === 'bigint' ? v.toString() : JSON.stringify(v)}`
    ])).join(', ')
  + '}';

console.log(stringify(o));

请注意,上述方法在许多情况下都不能正确工作,尤其是嵌套的对象和数组。如果我要在实际应用中使用这种方法,我可能会以Douglas Crockford的JSON实现为基础。只需在this line周围添加一个额外的情况即可。
case "bigint":
  return value.toString();

1
很奇怪,JavaScript对象表示法API很难使用...从JavaScript来看。但是现在是2020年。 - Paul Draper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接