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

手动生成JSON对象或数组时,通常会更容易在对象或数组的最后一项上留下尾随逗号。 例如,从一个string数组中输出的代码可能看起来像(在一个类似于伪代码的C ++中):

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

给你一个像

  [0,1,2,3,4,5,] 

这是允许的吗?

不幸的是,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("]"); 

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

另一个我用从某种forms的字典向JSON输出结构的替代方法是在每个条目之后总是附加一个逗号(如上面所做的那样),然后在末尾添加一个没有尾随逗号的虚拟条目(但这只是懒惰; – >)。

不幸的是不能很好的与数组配合。

不可以。在http://json.org上维护的JSON规范不允许使用尾随逗号。; 从我所看到的,一些parsing器可能默默地允许他们阅读JSONstring时,而其他人会抛出错误。 为了互操作性,您不应该包含它。

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

简单,便宜,易于阅读,并始终工作,无论规格。

 $delimiter = ''; for .... { print $delimiter.$whatever $delimiter = ','; } 

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

在JavaScript中允许使用尾随逗号,但在IE中不起作用。 道格拉斯·克罗克福德(Douglas Crockford)的无版本的JSON规范并不允许他们使用,而且因为它没有版本,所以不应该改变。 ES5 JSON规范允许它们作为扩展,但是Crockford的RFC 4627没有,ES5恢复为禁止它们。 Firefox也效仿。 Internet Explorer是为什么我们不能有好的东西。

PHP编码器可能想检出implode() 。 这需要一个数组使用一个string连接起来。

从文档 …

 $array = array('lastname', 'email', 'phone'); echo implode(",", $array); // lastname,email,phone 

正如已经说过的,JSON规范(基于ECMAScript 3)不允许尾随逗号。 ES> = 5允许它,所以你可以在纯JS中使用这个符号。 有人争辩说,一些parsing器确实支持它( http://bolinfest.com/essays/json.html,http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas- 不再被接受/ ),但它是规范的事实(如http://json.org/所示),它;不应该在JSON中工作。 那件事说…

…我想知道为什么没有人指出你可以实际上在第0次迭代中分割循环,并使用前导逗号而不是尾随一个去掉循环中的比较代码异味和任何实际的性能开销,导致与其他解决scheme相比,代码实际上更短,更简单和更快(由于循环中没有分支/条件)。

例如(与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("]"); 

有趣的是,C&C ++(和我认为C#,但我不确定)特别允许尾随逗号 – 正是由于这个原因:它使编程生成列表更容易。 不知道为什么JavaScript没有效仿。

使用JSON5。 不要使用JSON。

  • 对象和数组可以有尾随逗号
  • 如果对象键是有效的标识符,则可以不加引号
  • string可以单引号
  • string可以分成多行
  • 数字可以是hex(基数为16)
  • 数字可以以小数点开始或结束(开头或结尾)。
  • 数字可以包括Infinity和-Infinity。
  • 数字可以以明确的加号(+)开头。
  • 内联(单行)和块(多行)注释都是允许的。

http://json5.org/

https://github.com/aseemk/json5

从过去的经验来看,我发现不同的浏览器在处理JSON中的尾随逗号时有所不同。

Firefox和Chrome都可以处理它。 但IE浏览器(所有版本)似乎打破。 我的意思是真的打破了,停止阅读脚本的其余部分。

记住这一点,并且写出符合规范的代码总是很好,我build议花费额外的努力来确保没有尾随逗号。

🙂

我保持目前的计数,并将其与总数进行比较。 如果当前计数小于总计数,则显示逗号。

如果您在执行JSON生成之前没有总数,则可能无法正常工作。

再次,如果您使用PHP 5.2.0或更高版本,则可以使用内置的JSON API来格式化您的响应。

根据JSONArray类的规范 :

  • 一个额外的,(逗号)可能出现在右括号之前。
  • (逗号)省略时,将插入空值。

所以,据我了解,应该允许写:

 [0,1,2,3,4,5,] 

但可能发生的一些parsing器将返回7作为项目数(如丹尼尔Earwicker指出的IE8),而不是预期的6。


编辑:

我发现这个JSONvalidation器validation了针对RFC 4627的JSONstring(用于JavaScript对象表示法的应用程序/ json媒体types)和JavaScript语言规范。 其实这里有一个尾随逗号的数组只适用于JavaScript,而不适用于RFC 4627规范。

但是,在RFC 4627规范中指出:

2.3。 数组

数组结构表示为围绕零个或多个值(或元素)的方括号。 元素由逗号分隔。

 array = begin-array [ value *( value-separator value ) ] end-array 

对我来说,这又是一个解释问题。 如果你写的元素是用逗号分开的 (没有说明特殊情况,比如最后一个元素),可以用两种方式来理解。

PS RFC 4627不是一个标准(正如明确指出的那样),并且已经被RFC 7159(这是一个build议的标准)提供了RFC 7159

我通常遍历数组并在string中的每个条目之后附加一个逗号。 循环后我再次删除最后一个逗号。

也许不是最好的方法,但比每次检查都要便宜,如果它是循环中的最后一个对象,我想。

这是不推荐的,但你仍然可以这样parsing它。

 jsonStr = '[0,1,2,3,4,5,]'; let data; eval('data = ' + jsonStr); console.log(data)