JSON键必须用引号括起来吗?

289

例子: 下面的代码是否符合JSON规范?

{
    precision: "zip"
}

还是我应该始终使用以下语法?(如果是这样,为什么?)

{
    "precision": "zip"
}

我在JSON规范中没有找到关于这个的具体说明,尽管在他们的示例中使用引号包围键。

8个回答

177

是的,你需要引号。这是为了使其更简单,并避免需要另一种JavaScript保留关键字的转义方法,例如 {for:"foo"}


15
在许多情况下,引号并不简化操作,比如手动编辑的配置文件。JSON作为几乎通用的交换格式被使用(和误用)的不幸之处在于它具有特定于JavaScript的功能。 - miguel
17
真正的原因 - 也请查看这个答案 - https://dev59.com/0W855IYBdhLWcg3wrGdY - TechMaze
3
简述:他们不想应对ECMAScript中保留关键字(未加引号的)作为键的限制,因此要求所有键都加引号。 - BallpointBen

143

你正确地使用了字符串作为键。以下是取自《RFC 4627 - JavaScript对象表示法(JSON)的应用程序/json媒体类型》的摘录:

2.2. 对象

一个对象结构由一对花括号括起来,其中包含零个或多个名称/值对(或成员)。名称是一个字符串。每个名称后面跟着一个冒号,将名称与值分开。单个逗号将值与其后面的名称分开。对象中的名称应该是唯一的。

object = begin-object [ member *( value-separator member ) ] end-object

member = string name-separator value

[...]

2.5. 字符串

字符串的表示类似于C家族编程语言中使用的约定。一个字符串以引号开始和结束。[...]

string = quotation-mark *char quotation-mark

quotation-mark = %x22 ; "

阅读完整的RFC,请在这里阅读。


14
为了完整表达,第2.5节说:“一个字符串以引号开始和结束。” - rakslice

16

2.2.对象开始

对象结构表示为一对花括号,其中包含零个或多个名称/值对(或成员)。名称是一个字符串。

以及从2.5.字符串

字符串以引号开头和结尾。

因此,根据标准,我会说:是的,您应该始终引用键(尽管有些解析器可能更宽容)。


12

如果使用JSON5,就不需要引号了

对于常规的JSON,是的,键必须要用引号括起来。但如果你需要其他方式,可以看看广泛使用的JSON5,它被命名为超集,因为它允许ES5语法,包括:

  • 未用引号括起来的属性键
  • 单引号、转义和多行字符串
  • 备用数字格式
  • 注释
  • 额外的空格

JSON5的参考实现(json5 npm类库)提供一个JSON5对象,该对象具有与内置JSON对象相同的参数和语义的parsestringify方法。

广泛使用,并被许多高调项目所依赖

JSON5成立于2012年,截至2022年,现在每周有超过65M次下载,排名npm上最常用的软件包的前0.1%,并已被主要项目如Chromium, Next.js, Babel, Retool, WebStorm等采用。 它也在Apple平台上(如MacOS和iOS)得到本地支持。

~ json5.org 网站首页


4
哇,救了我的一天...我在这个破事上花费的时间太多了...而JSON5解析解决了它。 - RanH

9

1

JSON

JSON 格式中,键必须用引号括起来。

JSON 示例:

{
    "name": "John",
    "age": 30
}

JSON5

JSON5 是 JSON 的超集,它在原始的 JSON 格式基础上添加了一些额外的功能,包括使用单引号或未加引号的键。

JSON5 示例:

{
    // This is a comment
    name: 'John',
    'age': 30,
}

Hjson

Hjson 还允许键名不用加引号,只要它们不含空格或其他特殊字符。Hjson 本质上是 JSON/JSON5 的一种更为自由和宽容的版本,它允许数据格式和语法更具灵活性。

Hjson 示例:

{
  // This is a comment
  name: John
  age: 30
  city: New York
  favorites: [
    pizza
    ice cream,
  ]
}

0
在您的情况下,两者都是有效的,这意味着两者都可以工作。
然而,您仍应该使用在键名中带有引号的那个,因为它更加“传统”,这会导致更简单和能够使用带有空格等键名。
因此,请使用带引号的那个。
编辑// 检查此内容:JSON 和对象字面量符号之间有什么区别?

2
这可能更传统,但也需要更多的打字。 - Martin Rattigan
在 OP 中的两个选项中,只有带引号的那个是有效的 JSON。另一个不是。它们不能互换使用。它们唯一共同适用的地方是作为 JS 代码,而不是 JSON。JSON 和对象字面量表示法之间有什么区别? 因此,在问题所问的上下文中,引号并不是“更常规”的 - 它们是唯一的约定。 - VLAZ
@VLAZ是正确的,这就是为什么我写了“在你的情况下”。 - wolfenblut

-4

既然你可以使用“parent.child”点符号,也可以使用有效且有用的parent["child"],我认为两种方式都是技术上可接受的。解析器应该都能很好地处理这两种方式。如果您的解析器不需要键上的引号,则最好不要放置它们(节省空间)。将它们称为字符串是有道理的,因为它们就是字符串,并且由于方括号使您能够使用值作为键,因此不使用引号是完全合理的。在Json中,您可以放置...

>var keyName = "someKey";
>var obj = {[keyName]:"someValue"};

>obj
Object {someKey: "someValue"}

没有问题,如果你需要一个键的值,而没有引号不起作用,所以如果它不起作用,你就不能这样做,所以你不需要在键上加引号。即使技术上说它们是字符串,逻辑和使用也会有不同的看法。在我们的示例中,它也不会正式输出对象 {"someKey": "someValue"},在任何浏览器控制台运行。


3
被接受的答案和定义JSON的RFC都表明引号是必需的。 - Keith Thompson
这是正确的,但值得注意的是,从逻辑上讲它并不需要。我想,所有浏览器控制台的JavaScript对象表示法输出都是错误的,我们应该告诉某人去修复它。也许浏览器控制台输出的对象不是JSON,因此,正如规范定义的那样,JSON在大多数地方既不需要也没有实现。无论如何,我只是想说明一下,以不同的角度看待事实。实际上,也许规范应该被改变,“引用键”在我个人关心的任何地方都不是必需的。(在实践中就不是这样使用的。) - Master James
4
你混淆了三个不同的东西:JSON、JavaScript 对象字面量和浏览器开发工具控制台输出。当你在控制台中输入 obj 时,浏览器会显示对象的某些可读表示。它可以将其显示为对象字面量(就像在你的示例中所做的那样),或者它可能使用其他表示形式,甚至是交互式的形式。如果键名是有效的标识符且不是保留字,JavaScript 对象字面量不需要在键名周围加引号。然而,JSON 总是要求在键名周围加上引号。 - Michael Geary
5
进一步举例来说,不要在控制台中键入 obj,而是尝试 JSON.stringify(obj)。现在,您将看到对象的有效 JSON 表示,包括带引号的键名。相反,如果想要查看字符串是否为有效的 JSON,请尝试 JSON.parse(string)。如果键没有用引号括起来,这将会抛出异常。例如,JSON.parse('{"a":"b"}') 将会成功,但是 JSON.parse('{a:"b"}') 将会失败。 - Michael Geary
2
另一方面,你使用 var obj = {[keyName]:"someValue"}; 的方式非常有趣!我不知道在 JavaScript 对象字面量中可以这样做。经过一些检查,发现这是 ES6 中的新功能 - 在 ES5 中无法实现。 - Michael Geary
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接