您可以在JSON对象中使用结尾逗号吗?


392

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

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

给你一个像

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

可以吗?


66
几天前,这是我需要在网上查找的内容。我在此处未找到任何答案,因此在执行站点任务后,我提出了问题并回答了问题,以便其他人可以找到它。这是Jeff明确表示他想在这里做的事情。
本·康比

5
正如Jeff所说,我认为将SO用作您必须花一些时间查找的事情的“笔记本”非常好。当然,这只是这些类型项目的简单端,但是我仍然认为这是适当的,尤其是因为不同的javascript引擎将对此进行不同的处理。
pkaeding

6
我也想知道,所以这是一个完全合理的问题。
hoju

48
对于那些有人问一个简单问题的bit子,请退后一步。这是Google上的第一批热门歌曲之一,它帮助我快速参考了答案。谢谢你,OP。

40
有趣的是(或令人恐惧的)在IE 8中,我刚刚发现它alert([1, 2, 3, ].length)会显示“ 4”。
Daniel Earwicker 2010年

Answers:


250

不幸的是,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循环中多余的一行代码几乎不昂贵...

从某种形式的字典将结构输出到JSON时,我使用的另一种替代方法是始终在每个条目之后添加一个逗号(如您在上面所做的那样),然后在没有尾随逗号的末尾添加一个虚拟条目(但是那只是懒惰;->)。

不幸的是,不适用于数组。


2
正是由于这个原因,我已经开始在我的所有JS代码中使用这种格式(在同一行中的项目前的逗号)。使多余的逗号更加容易发现,并节省大量时间。这很烦人,我希望可以使用firefox为此抛出一个错误(因为这将有助于调试)。
火箭猴2011年

47
ECMA5指定尾部确实很可惜,而JSON却没有。
FlavorScape 2013年

4
是的,那条额外的线几乎不贵,但仍然很麻烦。
勒内Nyffenegger

2
此方法适用于索引的for循环。在样式循环中怎么样?有优雅的方法吗?
kgf3JfUtW

2
处理属性时,多余的一行代码可能很复杂。您可能会发现自己有很多ifs只是为了避免该愚蠢的小逗号。关于昂贵的YMMV,请参见jsfiddle.net/oriadam/mywL9384。说明 :您的解决方案很棒,我讨厌讨厌用逗号结尾的规范。
oriadam '17年

133

不能。JSON规范(在http://json.org上维护)不允许尾随逗号。据我了解,某些解析器在读取JSON字符串时可能会默默地允许它们,而其他解析器则会抛出错误。为了实现互操作性,您不应将其包括在内。

上面的代码可以进行重组,以在添加数组终止符时删除结尾的逗号,或者在项目前添加逗号,而跳过第一个逗号。


1
ECMA 262似乎在11.1.5对象初始化程序一节中定义了它。这是否好,似乎在规格中。
零分心2012年

6
有效的ECMAScript不一定意味着文档是有效的JSON-JSON通常在RFC 4627中定义,并且该规范不允许尾随逗号。
蒂姆·吉尔伯特

1
@ZeroDistraction:ECMA262定义ECMAscript(也称为javascript),这是一种编程语言,如Perl,Ruby,C ++或Java。JSON是XML,CSV或YAML等数据格式。它们不是同一件事。JSON在EXMA262中不存在,但是它派生的语法确实存在,它称为对象文字表示法(JSON中的ON)。
slebetman '16

106

简单,便宜,易于阅读,并且无论规格如何都可以正常工作。

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

$ delim的冗余分配要付出的代价很小。如果没有显式循环,但有单独的代码片段,则效果也一样。


1
在这种情况下,我通常就是这样做的。我觉得通过消除在替代方法(stackoverflow.com/a/201856/8946)中的值之前附加逗号所需的条件,额外的分配远远超过了抵消。
劳伦斯·多尔

5
我不喜欢这种解决方案,因为还有另一个变量污染了我的范围。一个if比较容易掌握。但是感谢您的分享。
2015年

3
另外,最好包含分隔符的范围:for(let ..., sep=""; ... ; sep=",") { ...
Lawrence Dol

1
我喜欢这种方法,因为它避免了有条件的操作,尽管现代CPU具有良好的分支预测逻辑。另请参见为什么处理排序数组要比未排序数组快?
侯赛因

21

JavaScript中允许使用逗号结尾,但在IE中则不起作用。道格拉斯·克罗克福德(Douglas Crockford)的无版本JSON规范不允许使用它们,并且由于它是无版本的,因此不应更改。ES5 JSON规范允许将它们作为扩展,但Crockford的RFC 4627不允许,并且ES5恢复为不允许它们。Firefox也效仿。Internet Explorer是我们不能拥有美好事物的原因。


1
我只是在IE 11中毫无问题地尝试了它们。您在哪个版本的IE中进行过测试,发现它们会导致问题?
iconoclast 2014年

10
好像Crockford就是为什么我们不能拥有美好的事物。那和JSON中的注释
Hejazzman

当OP使用伪代码之类的C ++时,为什么还要提及Web浏览器?OP的问题不太可能与Web浏览器或JavaScript有关。
cowlinator'1

@cowlinator Ĵ AVA 小号 CRIPT ö bject Ñ浮选
forresthopkinsa

1
Javascript对象文字启发了这种格式,但JSON不适用于Javascript引擎
Cowlinator

13

就像已经说过的那样,JSON规范(基于ECMAScript 3)不允许尾随逗号。ES> = 5允许它,因此您实际上可以在纯JS中使用该表示法。它被争论,有些解析器支持它(http://bolinfest.com/essays/json.htmlhttp://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas- no-longer-accepted /),但规范事实(如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("]");

3
简单快速的代码示例。比提出的其他答案要好得多。
Trevor Jex

12

PHP编码人员可能想签出implode()。这需要一个数组使用字符串将其连接起来。

文档 ...

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

2
同样,JavaScript具有join()。大多数语言都有类似的方法,或者很容易编码。
丹·伯顿

16
PHP具有json_encode,它处理制作JSON的所有详细信息,而不仅仅是逗号。
Brilliand12年

这很酷!它如何应用于JSON?如何在解决他们的问题的过程中帮助OP?记住,“您可以在JSON对象中使用结尾逗号吗?” 是问题。
Rockin4Life33

7

有趣的是,C和C ++(以及我认为的C#,但我不确定)都明确允许尾随逗号-正是由于给出的原因:它使以编程方式生成列表更加容易。不确定为什么JavaScript没有遵循他们的领导。


13
ECMA已明确指定在即将到来的规范中允许使用逗号结尾:ejohn.org/blog/bug-fixes-in-javascript-2 还有另一个需要弄清楚JSON!= JS Object的原因。
2008年

PHP也允许它。我认为这是我喜欢的PHP的一项功能。; p
iconoclast 2014年

4

使用JSON5。不要使用JSON。

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

http://json5.org/

https://github.com/aseemk/json5


看起来不错,但是不添加新的数据类型似乎错失良机……当然,希望保留ECMAScript 5的严格子集会迫使,但仍然...
iconoclast 2014年

1
另外,多串字符串也很糟糕。我梦想着ES6多线。
Marco Sulla 2015年

10
不,那是可怕的建议。在所有现有的JSON库中,很少有支持这种扩展的库。而这一切都是非常可疑的“改进”。请勿通过这种新的虚假扩展名进一步破坏互操作性。
StaxMan

7
我相信花一生的时间来修复逗号会更可怕。
619271

3

有一种方法可以避免循环中的if分支。

s.append("[ "); // there is a space after the left bracket
for (i = 0; i < 5; ++i) {
  s.appendF("\"%d\",", i); // always add comma
}
s.back() = ']'; // modify last comma (or the space) to right bracket

2

根据Class JSONArray规范

  • 右括号前可能会出现一个多余的(逗号)。
  • 当省略号(逗号)时,将插入空值。

因此,据我了解,应该允许这样写:

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

但是有可能某些解析器将返回7作为项目计数(例如Daniel Earwicker指出的IE8)而不是预期的6。


编辑:

我发现此JSON验证程序可根据RFC 4627验证JSON字符串程序可(JavaScript对象表示法的application / json媒体类型)和JavaScript语言规范。实际上,在这里带有尾部逗号的数组仅对JavaScript有效,而对RFC 4627规范无效。

但是,在RFC 4627规范中声明:

2.3。数组

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

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

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

PS RFC 4627不是标准(明确声明),并且已被RFC 7159(这是提议的标准)所废止。RFC 7159


6
给出的语法规则尽可能精确。没有办法在它旁边value-separator没有value权利。文字也很具体。“值分离”仅在存在多个值时适用。因此,如果两个值彼此相邻,则它们之间用逗号分隔。如果有一个值(或者只看最后的值),则没有分隔符,因此没有逗号。
Steffen Heil

1

根据我过去的经验,我发现不同的浏览器对JSON中尾随逗号的处理方式不同。

Firefox和Chrome都能很好地处理它。但是IE(所有版本)似乎都坏了。我的意思是说真的要休息,不要再阅读其余的脚本了。

考虑到这一点,以及编写兼容代码始终很不错的事实,我建议您花更多的精力来确保没有尾随的逗号。

:)


1

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

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

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


1

使用Relaxed JSON,您可以使用尾部逗号,也可以只保留逗号。它们是可选的。

完全不需要使用逗号来解析类似JSON的文档。

看一下Relaxed JSON规范,您将看到原始JSON规范有多“嘈杂”。引号和引号太多了...

http://www.relaxedjson.org

您也可以使用此在线RJSON解析器尝试您的示例,并查看它是否正确解析。

http://www.relaxedjson.org/docs/converter.html?source=%5B0%2C1%2C2%2C3%2C4%2C5%2C%5D


宽松的JSON从技术上讲不适用于JSON。
user2864740 '18

您可以将rjson与json相互转换,因此完全适用。也很容易将其添加到您的工作流程中。
史蒂芬·斯潘金

这是假设下游使用者理解此非JSON。在任何一种情况下,转换为有效的JSON都需要删除逗号。
user2864740 '18

OP使用字符串开头。可以将字符串解析为json objectusing JSON.parse,也可以将其解析为using RJSON.parse。如果源是一个对象,我会同意你的观点,但事实并非如此。我看不出它在问题中提到downstream了哪里消耗了对象或字符串。
史蒂文·斯潘金

“当手动生成JSON对象或数组时,通常在对象或数组的最后一项上留下逗号是更容易的。 [ JSON ]中是否允许?” -因此,再次:尽管这是一种有趣的替代格式,但它不是JSON,从技术上讲不适用于有关JSON的问题。没有什么“保卫”:这是为Z提案问题X.
user2864740

0

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

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


0

不建议这样做,但是您仍然可以执行类似的操作来解析它。

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


0

由于使用了for循环来遍历数组或类似的可迭代数据结构,因此我们可以使用所示数组的长度,

awk -v header="FirstName,LastName,DOB" '
  BEGIN {
    FS = ",";
    print("[");
    columns = split(header, column_names, ",");
  }
  { print("  {");
    for (i = 1; i < columns; i++) {
      printf("    \"%s\":\"%s\",\n", column_names[i], $(i));
    }
    printf("    \"%s\":\"%s\"\n", column_names[i], $(i));
    print("  }");
  }
  END { print("]"); } ' datafile.txt

随着datafile.txt包含,

 Angela,Baker,2010-05-23
 Betty,Crockett,1990-12-07
 David,Done,2003-10-31

0

如上所述,这是不允许的。但是在JavaScript中,这是:

var a = Array()
for(let i=1; i<=5; i++) {
    a.push(i)
}
var s = "[" + a.join(",") + "]"

(在Firefox,Chrome,Edge,IE11中正常运行,而在IE9、8、7、5中不放任)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.