JSON和JavaScript对象有什么区别?

120

我对JSON和JavaScript对象很陌生。

  • 有人能否解释一下JSON和JavaScript对象之间的区别?
  • 它们的用途是什么?
  • 其中一个更好还是另一个更好?还是要根据情况而定?
  • 在什么情况下使用哪个?
  • 为什么首先创建了JSON?它的主要目的是什么?
  • 有人能举例说明何时应该使用JSON而不是JavaScript对象,反之亦然吗?

2
请一次只提一个问题。 - Lightness Races in Orbit
@LightnessRacesinOrbit 你很棒! - Félix Adriyel Gagnon-Grenier
@FélixGagnon-Grenier 谢谢您。 - Lightness Races in Orbit
3个回答

174

首先,您应该知道什么是JSON:

  • 它是一种语言无关的数据交换格式。

JSON的语法受JavaScript对象字面量符号的启发,但它们之间存在差异。

例如,在JSON中,所有键都必须加引号,而在对象字面量中则不需要:

// JSON:
{ "foo": "bar" }

// Object literal:
var o = { foo: "bar" };

在JSON中必须使用引号是因为在JavaScript(更确切地说是在ECMAScript第3版)中,将保留字作为属性名是不允许的,例如:

var o = { if: "foo" }; // SyntaxError in ES3

使用字符串字面量作为属性名(引用属性名)不会出现问题:

var o = { "if": "foo" }; 

因此,为了实现“兼容性”(以及可能更容易评估?),引号是必须的。

JSON中的数据类型还受限于以下值:

  • string(字符串)
  • number(数字)
  • object(对象)
  • array(数组)
  • 文本字面量:
    • true(真)
    • false(假)
    • null(空)

Strings 的语法有所改变。它们必须用双引号括起来,而在JavaScript中,你可以随意使用单引号或双引号。

// Invalid JSON:
{ "foo": 'bar' }

Numbers 的 JSON 语法也有所改变,在 JavaScript 中可以使用十六进制字面量,例如 0xFF,或(臭名昭著的)八进制字面量例如 010。但在 JSON 中只能使用十进制字面量。

// Invalid JSON:
{ "foo": 0xFF }

有一些错误的实现(Firefox 3.5+,IE8+,json2.js)允许使用八进制字面量,例如JSON.parse('01')应该产生一个SyntaxError


@CMS已经很好地描述了它,但我想说你可以通过JSON实际代表的内容来区分它...也就是JavaScript对象“符号”! - Alex
57
很好的回答,但需要强调子集关系:任何有效的JSON声明也是有效的JavaScript声明,但并非所有有效的JavaScript声明都是JSON声明。 - Daniel Earwicker
1
另外展示JSON出现在JavaScript文件中唯一的方式也是有帮助的;即在字符串内部。 - Lightness Races in Orbit
5
并非所有有效的 JSON 必定是 JavaScript 中有效的对象表达式:http://timelessrepo.com/json-isnt-a-javascript-subset 某些 Unicode 空格字符在 JSON 字符串中有效但不在 JavaScript 中。 - Eamon Nerbonne
1
@EamonNerbonne - 如该页面所述,只有在极少数情况下它会导致问题时,修复它是非常容易的。 - Daniel Earwicker
1
这是一个潜在的崩溃错误问题,如果攻击者嵌入\u2028字符并且您(有效的)JSON序列化程序没有转义它们(因为不需要),任何包含JSON文本并将其作为JS对象评估的页面都可能遇到异常。在序列化程序级别很容易解决,但很痛苦,因为它不是一个正确的子集 - 然后您可以可靠地嵌入(有效的)JSON到JavaScript中而不会有风险。这主要只是令人恼火,没有更多的东西 - 当然了 :-)。 - Eamon Nerbonne

28

JSON是一个对象的字符串表示形式,它是一种可互操作的序列化格式。它不仅局限于JavaScript。例如,有针对 .NET 的JSON序列化程序,允许您序列化/反序列化.NET对象。

因此,它只是一种格式,允许您将对象转换为字符串并返回,这在传输数据时非常方便。

它非常接近JavaScript对象表示形式,如果您简单地使用 eval() 函数对JSON字符串进行求值,您将获得相应的对象。


3
不要让Crockford听到你说那个... - nickf
4
@nickf,Crockford的json2.js库正是这样做的,在一些“正则表达式验证”后进行eval,它并没有进行解析。事实上,即使是他自己的库,也有一些偏差和他自己的RFC不同!例如,json2.js可以错误地“解析”八进制字面量,例如:JSON.parse("01")……我觉得这很有趣:P - Christian C. Salvadó
@CMS 好吧,我猜Doug会反对使用“仅仅eval()”这个词语...(不包括正则表达式验证等) - nickf
所以,如果我只是编写一个需要使用对象的 JavaScript 程序,那么我不应该使用 JSON,因为我并没有将对象发送到其他地方? - Pheap
1
并非所有的JSON字符串都是有效的JS。链接 - Bergi
我应该将它们中的哪一个传递给JSON.stringify()函数? - Fortune

2
JSON是一种数据交换格式,看起来像是YAML或JavaScript代码的子集,您可以执行它并获得一个对象。JavaScript对象只是JavaScript中的一个对象。
由于JSON是一种数据交换格式,因此您可以使用它以文本形式交换结构化数据。现在它与JavaScript相当解耦。JavaScript对象允许您在JavaScript程序执行期间创建和处理结构化数据。

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