JSON 现行标准 RFC7159 [1] 和 ECMA-404 [2] 明确地定义 JSON 的功能是数据互换格式(data interchange format)。作为互换格式,本身就应该尽量简单,避免一些可有可无的语法。我认为「最后可加逗号」算是可有可无的语法。
虽然如此,我觉得现在还是有一些可有可无的语法。例如字符串里的 (斜线符)可表示为 也可表示为转义形式 。另外,数字范围也是个比较大的问题,[1] 里说由实现决定,而又由于有些实现统一用双精度来表示数字,那么就不能处理很常见的 64 位整数。
身为 RapidJSON 的作者,希望这个库能提供最严格的 JSON 语法校验,但同时,不少使用者都想放宽限制,有不少相关讨论 [3],我简单翻译一些扩展语法需求:
贫穷限制了我的想像力,甚至,曾经有使用者希望可以支持数字运算表达式⋯⋯
即使不考虑上述的扩展语法,许多开源的 JSON 解析器/生成器也不能完全符合标准。我在 [5] 测试开源库性能的同时,也测试了它们是否合符标准(有少部分测试高于标准要求,例如完美还原数字):
因此,个人认为 JSON 标准还是尽量简单好一些,再复杂、再多可有可无的语法,只会令应用时出现更多问题。所以,我对题目是否定的,这不是错误设计,而是一个合理的设计。如果考虑把 JSON 扩展成适合用于人手编写的格式,或许可考虑 YAML 和 JSON5 等。
更新:看到有答案说输出 JSON 很麻烦。我只想回应:
不要手工编码输出 JSON!
不要手工编码输出 JSON!
不要手工编码输出 JSON!
你知道你用的语言/运行时所输出的数字必定合符 JSON 要求么?你有处理字符串里的字符转义么?
就算不使用 DOM,有些库(如 RapidJSON)还提供最简单的 SAX 风格 API:
StringBuffer s; Writer<StringBuffer> writer(s); writer.StartArray(); for (int i = 1; i <= 5; i++) writer.Int(i); writer.EndArray(); std::cout << s.GetString(); // [1,2,3,4,5]
让程序库处理逗号,不要每次都做轮子。
[1] The JavaScript Object Notation (JSON) Data Interchange Format
[3] Strict/Relaxed JSON syntax · Issue #36 · Tencent/rapidjson
[4] The application/json Media Type for JavaScript Object Notation (JSON)
设不是设计错误,也不是parse的问题,完全就是为了规则简单,就像属性名必须加引号一样。
事实上很多解析器也是可以处理不规范格式的。