你能在JSON对象中使用尾随逗号吗?

Ben*_*bee 373 syntax json delimiter

手动生成JSON对象或数组时,通常更容易在对象或数组中的最后一项上留下尾随逗号.例如,从字符串数组输出的代码可能看起来像(在像C++这样的伪代码中):

s.append("[");
for (i = 0; i < 5; ++i) {
    s.appendF("\"%d\",", i);
}
s.append("]");
Run Code Online (Sandbox Code Playgroud)

给你一个字符串

[0,1,2,3,4,5,]
Run Code Online (Sandbox Code Playgroud)

这是允许的吗?

bri*_*anb 236

不幸的是,JSON规范不允许使用尾随逗号.有一些浏览器允许它,但通常你需要担心所有的浏览器.

一般情况下,我尝试解决问题,并在实际值之前添加逗号,因此您最终得到的代码如下所示:

s.append("[");
for (i = 0; i < 5; ++i) {
  if (i) s.append(","); // add the comma only if this isn't the first entry
  s.appendF("\"%d\"", i);
}
s.append("]");
Run Code Online (Sandbox Code Playgroud)

for循环中额外的一行代码并不昂贵......

我在从某个表单的字典输出结构到JSON时使用的另一个替代方法是在每个条目之后总是附加一个逗号(如上所述),然后在末尾添加一个没有尾随逗号的虚拟条目(但是那只是懒惰; - >).

不幸的是,对阵列不适用.

  • 非常遗憾ECMA5指定了追踪,但JSON没有. (37认同)
  • 是的,那条额外的线几乎不贵,但仍然很麻烦。 (3认同)
  • 正是由于这个原因,我已经开始在我的所有JS代码中使用这种格式(同一行中项目前的逗号)。使多余的逗号更加容易发现,并节省了大量时间。这很烦人,我希望可以使用firefox为此抛出一个错误(因为这将有助于调试)。 (2认同)
  • 此方法适用于索引的for循环。在样式循环中怎么样?有优雅的方法吗? (2认同)
  • 在处理属性时,额外的一行代码可能会很复杂。你可能会发现自己有很多“如果”只是为了避免那个愚蠢的小逗号。关于昂贵的 YMMV,请参见例如 https://jsfiddle.net/oriadam/mywL9384/ 澄清:您的解决方案很棒,我只是讨厌禁止尾随逗号的规范。 (2认同)

Ben*_*bee 128

不.在http://json.org上维护的JSON规范不允许使用尾随逗号.从我所看到的,一些解析器可能在读取JSON字符串时默默地允许它们,而其他解析器会抛出错误.对于互操作性,您不应包含它.

上面的代码可以重新构造,要么在添加数组终止符时删除尾随逗号,要么在项目之前添加逗号,跳过第一个代码.

  • 有效的ECMAScript并不一定意味着文档是有效的JSON - JSON通常在[RFC 4627](http://www.ietf.org/rfc/rfc4627.txt)中定义,并且该规范不允许使用尾随逗号. (5认同)
  • 这是问题的正确答案. (3认同)

小智 102

简单,便宜,易于阅读,无论规格如何,始终可以使用.

$delimiter = '';
for ....  {
    print $delimiter.$whatever
    $delimiter = ',';
}
Run Code Online (Sandbox Code Playgroud)

$ delim的冗余分配是一个非常小的代价.如果没有显式循环但是单独的代码片段,也可以正常工作.

  • 我不喜欢这个解决方案,因为有另一个变量污染了我的范围.一个`if`更容易掌握.但感谢分享. (5认同)
  • 另外,最好包含分隔符的范围:`for(let ...,sep =""; ...; sep =","){...` (3认同)
  • 这就是我在这种情况下通常会做的事情;我认为通过消除在替代方法(http://stackoverflow.com/a/201856/8946)中的值之前附加逗号所需的条件,额外的分配不仅仅是抵消。 (2认同)

Tob*_*obu 19

JavaScript中允许使用尾随逗号,但在IE中不起作用.道格拉斯克罗克福德的无版本JSON规范不允许它们,因为它是无版本的,所以不应该改变.ES5 JSON规范允许它们作为扩展,但Crockford的RFC 4627没有,并且ES5恢复禁止它们.Firefox紧随其后.Internet Explorer是我们不能拥有好东西的原因.

  • 好像Crockford就是为什么我们不能拥有美好的东西.那和JSON中的评论 (9认同)
  • @cowlinator **J**ava**S**cript **O**bject **N**otation (3认同)

Rik*_*ood 14

PHP编码器可能想要检查implode().这需要一个数组使用字符串连接它.

来自文档 ......

$array = array('lastname', 'email', 'phone');
echo implode(",", $array); // lastname,email,phone
Run Code Online (Sandbox Code Playgroud)

  • PHP有json_encode,它处理制作JSON的所有细节,而不仅仅是逗号. (15认同)
  • 同样,JavaScript有[join()](http://www.w3schools.com/jsref/jsref_join.asp).大多数语言都有类似的方法,或类似的方法可以很容易编码. (2认同)
  • python 有 join : ```','.join(mylist)``` (2认同)

vax*_*uis 13

正如已经说过的那样,JSON规范(基于ECMAScript 3)不允许使用尾随逗号.ES> = 5允许它,因此您可以在纯JS中实际使用该表示法.它被争论,有些解析器支持它(http://bolinfest.com/essays/json.html,http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-不再接受/),但它是规范事实(如http://json.org/所示)它不应该在JSON中工作.那件事说......

...我想知道为什么没有人指出你实际上可以在第0次迭代时拆分循环并使用前导逗号而不是尾随逗号来摆脱比较代码气味和循环中的任何实际性能开销,从而导致实际上比其他解决方案更短,更简单,更快(由于循环中没有分支/条件)的代码.

例如(在类似于OP提议的代码的C风格伪代码中):

s.append("[");
// MAX == 5 here. if it's constant, you can inline it below and get rid of the comparison
if ( MAX > 0 ) {
    s.appendF("\"%d\"", 0); // 0-th iteration
    for( int i = 1; i < MAX; ++i ) {
        s.appendF(",\"%d\"", i); // i-th iteration
    }
}
s.append("]");
Run Code Online (Sandbox Code Playgroud)

  • 简单快速的代码示例.比其他答案提出的解决方案要好得多. (3认同)

Rol*_*and 12

与其加入辩论俱乐部,因为还有更大的问题需要解决,我会坚持Defensive Programming结合两种简单技术来简化与他人交流的原则:

  1. 作为接收json 数据的应用程序的开发人员,我会放松允许尾随逗号。

  2. 在开发编写json的应用程序时,我会严格并使用其他答案的巧妙技术之一,仅在项目之间添加逗号并避免尾随逗号。

  • 这被称为 Postel 规则:https://en.wikipedia.org/wiki/Robustness_principle (2认同)
  • 不幸的是,这是一个极其糟糕的主意。您应该准确执行规范并大声拒绝所有不合格的输入。鲁棒性原则导致了数十种实现,所有实现都做了细微不同的事情,导致咬牙切齿。有多种输入方式超出规范;没有两个实现者会以完全相同的方式进行扩展。用户将针对一种实现准备数据,然后使其无法在另一种实现中工作。 (2认同)
  • @Kaz 你当然有道理。但我因开发工作应用程序而获得报酬,而不是因抱怨输入错误的错误消息而停止的应用程序。坏的?以 HTML 为例。如果浏览器很严格,大多数网站都会停止工作。哎呀,现在我被引诱进入辩论了。。。 (2认同)
  • 没问题; 为了提高工作效率,请务必使用一个编译器,它会默默地为您关闭大括号等。 (2认同)

Jam*_*ran 7

有趣的是,C&C++(我认为C#,但我不确定)特别允许尾随逗号 - 正是由于给出的原因:它使程序化生成列表变得更加容易.不确定为什么JavaScript没有跟随他们的领先优势.

  • ECMA明确指出在即将发布的规范中允许使用尾随逗号:http://ejohn.org/blog/bug-fixes-in-javascript-2/另一个明确JSON!= JS Object的原因. (12认同)
  • 尾随逗号在Firefox中有效,但在IE中则无效. (6认同)

Ben*_*kin 7

不。 https://json.org中的“铁路图”是规范的精确翻译,并明确指出 a,始终出现在 a 之前value,而不是直接出现在 之前]

数组的铁路图

或者}

对象的铁路图


use*_*271 5

使用JSON5。不要使用JSON。

  • 对象和数组可以有逗号结尾
  • 如果对象键是有效的标识符,则可以将其取消引用
  • 字符串可以单引号
  • 字符串可以分为多行
  • 数字可以是十六进制(以16为底)
  • 数字可以以(前导或尾随)小数点开头或结尾。
  • 数字可以包括Infinity和-Infinity。
  • 数字可以以显式加号(+)开头。
  • 允许内联(单行)和块(多行)注释。

http://json5.org/

https://github.com/aseemk/json5

  • 不,那是可怕的建议。在所有现有的JSON库中,很少有支持这种扩展的库。而这一切都是非常可疑的“改进”。请勿通过这种新的虚假扩展名进一步破坏互操作性。 (8认同)
  • 我相信花一生的时间来修复逗号会更可怕。 (6认同)