Javascript对象与JSON


208

我想清楚地了解Javascript对象和JSON字符串之间的基本区别。

假设我创建了以下JS变量:

var testObject = {one: 1,"two":2,"three":3};

Q1。密钥/属性名称在带/不带引号的情况下均有效吗?(例如"one" : 1

如果是,有什么区别?

问题2:如果我使用转换上述对象JSON.stringify(testObject),原始JS对象和JSON有什么区别?

我觉得他们几乎一样。请详细说明。

问题3:对于解析JSON字符串,是否建议使用以下方法?

var javascriptObj = JSON.parse(jSonString);

Answers:


239
  1. 密钥/属性名称在带/不带引号的情况下均有效吗?

    你需要使用对象的文字符号时放在引号的关键唯一的一次,其中关键包含特殊字符(if:-等)。值得注意的是,JSON中的密钥必须引号引起来。

  2. 如果我使用将上述对象转换为JSON var jSonString = JSON.stringify(testObject);,两者(JS obj和JSON)之间有什么区别?

    JSON是一种数据交换格式。这是一个标准,描述了如何在字符串中表示有序列表和无序映射,字符串布尔值和数字。就像XML和YAML是在语言之间传递结构化信息的一种方式一样,JSON也是如此。另一方面,JavaScript对象是物理类型。就像PHP数组,C ++类/结构一样,JavaScript对象是JavaScript内部的一种类型。

    这是一个故事。假设您从商店购买了一些家具,并且希望将其交付。但是,库存中仅剩一个是展示模型,但您同意购买。

    在商店中,您购买的抽屉柜是有生命的物品:

    var chestOfDrawers = {
        color: "red",
        numberOfDrawers: 4
    }

    但是,您不能在帖子中发送抽屉式的,所以您要拆除它(阅读,分类)。现在它在家具方面毫无用处。现在是JSON。扁平包装形式。

    {"color":"red","numberOfDrawers":4}

    收到后,您便可以重建抽屉柜(读取,解析)。现在以对象形式返回。

    JSON / XML和YAML背后的原因是使数据能够以参与语言都可以理解的格式在编程语言之间传输;您不能直接给PHP或C ++您的JavaScript对象;因为每种语言在引擎盖下代表的对象都不同。但是,由于我们已将对象分为JSON表示法;即表示数据的标准化方法,我们可以传输JSON 表示将对象到另一种语言(C ++,PHP),它们可以基于对象的JSON表示形式将我们拥有的JavaScript对象重新创建为自己的对象。

    请务必注意,JSON无法代表函数或日期。如果尝试使用函数成员对对象进行字符串化,则该函数将从JSON表示中省略。日期将转换为字符串;

    JSON.stringify({
        foo: new Date(),
        blah: function () { 
            alert('hello');
        }
    }); // returns the string "{"foo":"2011-11-28T10:21:33.939Z"}"
  3. 对于解析JSON字符串,是否建议使用以下方法? var javascriptObj = JSON.parse(jSonString);

    是的,但是较旧的浏览器本身不支持JSON(即<8)。为了支持这些,您应该包括json2.js

    如果您使用的是jQuery,则可以调用jQuery.parseJSON()JSON.parse()如果受支持,它将在后台使用,否则将回退到自定义实现中以解析输入。


4
@testndtv您缺少要点-尽管在纸上(或在屏幕上)JSON字符串和JS对象的显示可能看起来相同,但它们不是同一件事。JSON只是将对象打包为字符串的一种方法,因此可以将其传输到某个地方,然后再将其解压缩回一个对象。
Alnitak

1
@Matt可怜的类比恕我直言-JSON不应用于序列化具有方法的对象-仅用于纯数据对象。
Alnitak

1
因此,如果JS对象具有方法,将转换为JSON字符串将完全忽略它...就像在上述情况下一样,getIn和getOut将被完全忽略....这是如何工作的?
testndtv 2011年

3
@Growler:平时我使用JSON,如果要在“东西”的需求所产生的服务器上,并使用一个js文件,如果“东西”只是担任原样。另一个重要的区别是您是否需要包含函数和/或日期,因为JSON无法表示它们,因此您必须使用JS文件。如果您仍然不确定,请随时在Stack Overflow上作为一个单独的问题提问(显示您需要提供的表示对话框的内容示例),并通过链接向我展示;我很乐意仔细看看!
马特2014年

4
@Matt先生,您是天才!您的解释是现场的,清晰,简洁且易于理解的。我希望你是我的JavaScript /编程导师。
FrankDraws

30

问题1:在javascript中定义对象文字时,键可以包含引号,也可以不包含引号。没有任何区别,只是引号允许您指定某些键,如果您尝试裸键,这些键将导致解释器无法解析。例如,如果您想要一个只是感叹号的键,则需要使用引号:

a = { "!": 1234 } // Valid
a = { !: 1234 } //  Syntax error

但是,在大多数情况下,您可以省略对象文字上键周围的引号。

问题2:JSON实际上是字符串表示形式。它只是一个字符串。因此,请考虑以下问题:

var testObject = { hello: "world" }
var jSonString = JSON.stringify(testObject);

由于testObject是真实的对象,因此您可以在其上调用属性,并可以对对象执行其他任何操作:

testObject.hello => "world"

另一方面,jsonString只是一个字符串:

jsonString.hello => undefined

请注意另一个区别:在JSON中,所有键都必须加引号。这与对象文字相反,在对象文字中,根据我在Q1中的解释,通常可以省略引号。

Q3。您可以使用解析JSON字符串JSON.parse,这通常是最好的方式(如果浏览器或框架提供了此功能)。您也可以只使用evalJSON,因为JSON是有效的JavaScript代码,但出于多种原因,建议使用前一种方法(eval与之相关的问题很多)。


9

JSON解决的问题

假设您要在两台计算机之间交换常规JavaScript对象,并设置了两个规则:

  • 传输的数据必须是常规字符串。
  • 只能交换属性,不传输方法。

现在,您在第一个主机上创建两个对象:

var obj1 = { one: 1,"two":2,"three":3 }; // your example
var obj2 = { one: obj1.one, two: 2, three: obj1.one + obj1.two };

如何将这些对象转换为字符串以传输到第二个主机?

  • 对于第一个对象,您可以发送从文字定义中获取的此字符串'{ one: 1,"two":2,"three":3 }',但实际上您不能读取文档脚本部分中的文字(至少不容易)。因此obj1obj2实际上必须以相同的方式进行处理。
  • 您需要枚举所有属性及其值,并构建一个类似于对象文字的字符串。

JSON的创建是为了解决上述需求:它是一组规则,可通过列出所有属性和值来创建与对象等效的字符串(方法被忽略)。

JSON规范化了属性名称和值中双引号的使用。

请记住,JSON仅是一组规则(一个标准)。

创建了几个JSON对象?

只有一个,它是由JS引擎自动创建的。

在浏览器中发现的现代JavaScript引擎具有一个本机对象,也称为JSON。此JSON对象能够:

  • 使用JSON.parse(string)解码使用JSON标准构建的字符串。结果是一个常规JS对象,该对象具有在JSON字符串中找到的属性和值。

  • 使用JSON.stringify()编码常规JS对象的属性/值。结果是符合JSON规则集的字符串。

(单个)JSON对象类似于编解码器,它的功能是编码和解码。

注意:

  • JSON.parse()不会创建JSON对象,它会创建常规的JS对象,使用对象文字创建的对象与JSON.parse()从符合JSON的字符串创建的对象之间没有区别。

  • 只有一个JSON对象,该对象用于所有转换。

回到问题

  • 问题1:对象文字可以使用双引号中的单引号。请注意,引号可选地用于属性名称,并且对于字符串值是必需的。对象文字本身不被引号引起来。

  • Q2:从文字和使用JSON.parse()创建的对象严格相同。创建后这两个对象是等效的:

    var obj1 = { one: 1, "two": 2, "three": 3 };
    var obj2 = JSON.parse('{ "one": "1", "two": "2", "three": "3" }');

  • 问题3:在现代浏览器JSON.parse()上,用于根据JSON兼容的字符串创建JS对象。(jQuery还有一种等效方法,可用于所有浏览器)。


7

问题1-在JS中,仅当密钥为保留字或否则为非法令牌时,才需要使用引号。在JSON中,您必须始终在键名上使用双引号。

Q2- jsonString是输入对象的序列化版本...

Q3-可以使用以下方法反序列化为外观相同的对象JSON.parse()


1

问题已经发布了很好的答案,我在下面添加了一个小示例,这将使您更容易理解先前答案中的解释。将下面的代码段粘贴粘贴到您的IDE,以更好地理解并注释包含invalid_javascript_object_no_quotes对象声明的行,以避免编译时错误。

// Valid JSON strings(Observe quotes)
valid_json = '{"key":"value"}'
valid_json_2 = '{"key 1":"value 1"}' // Observe the space(special character) in key - still valid


//Valid Javascript object
valid_javascript_object_no_quotes = {
    key: "value"  //No special character in key, hence it is valid without quotes for key
}


//Valid Javascript object
valid_javascript_object_quotes = {
    key:"value",  //No special character in key, hence it is valid without quotes for key
    "key 1": "value 1" // Space (special character) present in key, therefore key must be contained in double quotes  - Valid
}



console.log(typeof valid_json) // string
console.log(typeof valid_javascript_object_no_quotes) // object
console.log(typeof valid_javascript_object_quotes) // object

//Invalid Javascript object 
invalid_javascript_object_no_quotes = {
   key 1: "value"//Space (special character) present in key, since key is not enclosed with double quotes "Invalid Javascript Object"
}
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.