每个 JSON 文档本身就已经是有效的 JavaScript 表达式。你可以将 JSON
粘贴到 const config = 赋值中并运行它。有趣的工作是反向的:真正的
JavaScript 对象字面量充满了 JSON 禁止的东西,而一个猜测它们含义的
转换器会在报告成功的同时丢失数据。
使用 JSON 到 JavaScript 转换器
选择方向并点击转换。写入 JavaScript 时,作为有效标识符的对象键
不加引号书写,因此 "name" 变成 name,而像 "display name" 这样的
键则保留引号,因为不加引号书写会改变其拼写。空对象或数组保持在一行。
数字通过令牌流而非 JSON.parse 传输,因此二十位整数会带全部二十位
数字返回。
读取器接受什么
将 JavaScript 读回 JSON 时,该工具理解你实际上会从配置文件粘贴的
对象字面量:不加引号的键、单引号字符串、// 和 /* */ 注释、
尾随逗号,以及开头的可选 const、let 或 var 名称和结尾的
分号。不含插值的模板字面量也被接受,因为它包含纯文本。
JSON 拒绝的数字拼写会被规范化为其确切的 JSON 形式:
const numbers = { a: .5, b: 5., c: 5.e3 }
{
"a": 0.5,
"b": 5,
"c": 5e3
}
什么被拒绝,以及为什么
JSON 无法容纳的任何内容都按名称被拒绝,而非被猜测。undefined、
NaN 和 Infinity 没有 JSON 数字或值,因此被拒绝。十六进制、八进制
和二进制数字、带下划线的数字分隔符(如 1_000)以及前导零也是如此,
如果 JSON 读取它们,所有这些都会改变含义。正则表达式、函数、裸词
和 ${...} 模板插值也被拒绝,因为这些是代码,不是数据。
有两个拒绝值得仔细查看。在一个对象中出现两次的键被拒绝,因为
JSON 无法在单个名称下保存两个值。而值为对象或 null 的 __proto__
键被拒绝,因为在 JavaScript 对象字面量中该拼写不会创建属性。它
设置新对象的原型,因此将其与普通 __proto__ 键一起转换为 JSON 会
发明一个原始代码从未拥有的属性。
为什么 undefined 默认不转换为 null
JSON 没有 undefined,因此转换器必须做些什么。写入 null 会静默地
改变数据的含义:配置对象中的 undefined 通常意味着字段尚未配置,
这与代码稍后检查的 null 不同。该工具默认拒绝,Convert undefined to
null 选项在你确实需要该含义时存在。
往返转换
将文档转换回另一种格式是引号和拒绝规则是否正确的真正测试。具有 不加引号的键、单引号和尾随逗号的对象字面量作为 JSON 返回,每个键 都加引号且每位数字完整,再次向前转换该 JSON 会返回相同的对象。错误 的规则通常只有在你转回并比较时才会显现。