Javascript 对象与 JSON

IT技术 javascript json
2021-02-02 02:17:30

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

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

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

一季度。带/不带引号的键/属性名称是否有效?(例如"one" : 1

如果是,有什么区别?

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

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

Q3:解析 JSON 字符串,是否推荐使用以下方法?

var javascriptObj = JSON.parse(jSonString);
5个回答
  1. 带/不带引号的键/属性名称是否有效?

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

  1. 如果我使用 将上述对象转换为 JSON var jSonString = JSON.stringify(testObject);,那么 2(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"}"
  1. 对于解析 JSON 字符串,是否推荐使用以下方法? var javascriptObj = JSON.parse(jSonString);

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

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

@Matt 糟糕的类比恕我直言 - JSON 不应该用于序列化具有方法的对象 - 仅适用于纯数据对象。
2021-03-24 02:17:30
@Matt 真的很喜欢家具的比喻。想看更多这样的,更通俗易懂的,赶紧抢了,忘不了。
2021-03-27 02:17:30
@testndtv 你没有抓住重点——尽管在纸上(或屏幕上)一个 JSON 字符串和一个 JS 对象显示可能看起来一样,但它们不是一回事。JSON 只是将对象打包成字符串的一种方式,因此可以将其传输到某个地方,然后再将其解包回对象。
2021-03-31 02:17:30
@Growler:平时我使用JSON,如果要在“东西”的需求所产生的服务器上,并使用一个js文件,如果“东西”只是担任原样。另一个重要的区别是您是否需要包含函数和/或日期,因为 JSON 不能表示它们,因此您必须求助于提供 JS 文件。如果您仍然不确定,请随时在 Stack Overflow 上将其作为一个单独的问题提出(展示您需要提供的内容示例以代表您的对话),并通过链接提示我;我很乐意仔细看看!
2021-04-01 02:17:30
@Matt 你先生,真是#king 天才!您的解释准确、清晰、简洁且易于理解。我希望你是我的 JavaScript/编程导师。
2021-04-04 02:17:30

Q1:在 javascript 中定义对象字面量时,键可能包含或不包含引号。没有什么区别,除了引号允许您指定某些键,如果您尝试使用它们会导致解释器无法解析。例如,如果您想要一个只是感叹号的键,则需要引号:

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

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

Q2:JSON 实际上是一种字符串表示。它只是一个字符串。所以,考虑一下:

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

因为它testObject是一个真实的对象,你可以调用它的属性并做任何你可以对对象做的事情:

testObject.hello => "world"

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

jsonString.hello => undefined

注意另一个区别:在 JSON 中,所有键都必须被引用。这与对象字面量形成对比,根据我在 Q1 中的解释,通常可以省略引号。

Q3。您可以使用 解析 JSON 字符串JSON.parse,这通常是最好的方法(如果浏览器或框架提供)。您也可以直接使用,eval因为 JSON 是有效的 javascript 代码,但出于多种原因推荐使用前一种方法(eval 有很多与之相关的令人讨厌的问题)。

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 标准构建的字符串。结果是具有在 JSON 字符串中找到的属性和值的常规 JS 对象。

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

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

注意:

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

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

回到问题

  • Q1:对象字面量允许使用单引号或双引号。请注意,引号可选择性地用于属性名称,并且对于字符串值是必需的。对象文字本身没有被引号包围。

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

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

  • Q3:在现代浏览器JSON.parse()上用于从符合 JSON 的字符串创建 JS 对象。(jQuery 也有一个等效的方法,可用于所有浏览器)。

在我看来,在 Q2 中,对象 obj1 和 obj2 实际上是不同的,因为 JSON 字符串包含字符串值“1”、“2”和“3”,而文字定义包含整数 1、2 和 3。
2021-03-24 02:17:30
@tebb:正确。我不应该对 obj2 中的数字使用字符串。要解析的字符串包含整数,那么 js 对象也包含整数(并且两个对象是相等的)
2021-03-31 02:17:30

Q1 - 在 JS 中,如果键是保留字或者它是非法标记,则只需要使用引号。在 JSON 中,您必须始终在键名上使用双引号。

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

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

问题已经发布了很好的答案,我在下面添加了一个小例子,这样可以更容易地理解之前答案中给出的解释。将下面的代码片段复制粘贴到您的 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"
}