JSON和对象文字表示法有什么区别?


219

有人可以告诉我使用对象文字表示法定义的JavaScript对象与JSON对象之间的主要区别是什么吗?

根据一本JavaScript书,它说这是使用Object Notation定义的对象

var anObject = {
    property1 : true,
    showMessage : function (msg) { alert(msg) }
};

为什么在这种情况下不是JSON对象?只是因为它不是通过使用引号定义的?


20
“在这种情况下为什么不是JSON对象?”:因为您的键必须是字符串,并且函数不是有效的JSON值。
马特2010年

Answers:


247

首先让我们澄清一下JSON实际上是什么。JSON是一种文本形式的,与语言无关的数据交换格式,非常类似于XML,CSV或YAML。

数据可以通过多种方式存储,但是如果应该将其存储在文本文件中并且可由计算机读取,则它需要遵循某种结构。JSON是定义这种结构的多种格式之一。

这样的格式通常与语言无关,这意味着它们可以通过Java,Python,JavaScript,PHP进行处理,只要您命名。

相反,JavaScript是一种编程语言。当然,JavaScript还提供了一种定义/描述数据的方法,但是语法非常特定于JavaScript。

作为反例,Python具有元组的概念,其语法为(x, y)。JavaScript没有这样的东西。


让我们看一下JSON和JavaScript对象文字之间的语法差异。

JSON具有以下语法约束:

  • 对象必须是字符串(即用双引号括起来的字符序列")。
  • 值可以是:
    • 一个字符串
    • 一个号码
    • (JSON)对象
    • 数组
    • true
    • false
    • null
  • 重复的键({"foo":"bar","foo":"baz"})会产生未定义的,特定于实现的结果;JSON规范没有明确定义其语义

在JavaScript中,对象文字可以具有

  • 字符串文字,数字文字或标识符名称作为键(自ES6开始,现在还可以计算键,这引入了另一种语法)。
  • 值可以是任何有效的JavaScript表达式,包括函数定义和undefined
  • 重复的键会产生已定义的指定结果(在松散模式下,后一个定义将替换前一个;在严格模式下,这是一个错误)。

知道了,仅查看语法,您的示例就不是JSON,原因有两个:

  1. 您的密钥不是字符串(文字)。它们是标识符名称
  2. 您不能将函数作为值分配给“ JSON对象”(因为JSON没有为函数定义任何语法)。

但最重要的是,从一开始就重复我的解释:您处于JavaScript上下文中。您定义一个JavaScript对象。如果有的话,“ JSON对象”只能包含在字符串中:

 var obj = {foo: 42}; // creates a JavaScript object (this is *not* JSON)
 var json = '{"foo": 452}'; // creates a string containing JSON

也就是说,如果您正在编写JavaScript源代码,并且没有处理字符串,那么您就不会处理JSON。也许您以JSON形式接收了数据(例如,通过ajax或从文件中读取),但是一旦您或所使用的库将其解析后,它就不再是JSON。


仅因为对象文字和JSON看起来相似,并不意味着您可以互换命名它们。另请参见没有“ JSON对象”之类的东西


8
还要注意,JSON是对象文字表示法的子集
Sean Kinsey,2010年


1
可能值得注意的是,通常您会期望在注释合法的上下文中使用JavaScript对象文字,并且JSON规范不允许注释(请参阅本文)
布赖恩·亨利

无论是否使用“”,对象文字中的键始终是字符串。
兑换

2
@overexchange:“对象文字中的键始终是字符串”您在这里混合了两件事,但是我不能怪您,因为我在这里也没有划清界限。您必须区分对象文字和对象。一个文字是你在源代码中写的字符序列。该是通过解释源代码创建的。对象文字(语法)允许您使用标识符名称字符串文字数字文字。您是正确的,在运行时,它们都将转换为字符串(但现在也有符号)。
费利克斯·克林(Felix Kling),2016年

41

JSON的语法非常有限,包括:

  • 键值必须加引号
  • 字符串必须用"而不是双引号引起来'
  • 您的值范围更有限(例如,不允许使用函数)

1
喜欢这个“没有功能允许”。
卡兰·考

也不允许评论。由于可疑的原因。(听到他们几次质疑。)这是我要说的主要区别
。– user7610

15

确实没有“ JSON对象”之类的东西。

JSON规范是将数据编码为字符串的语法。人们所谓的“ JSON对象”(在javascript中)实际上只是一个普通的javascript对象,它已经(可能)已从有效的JSON字符串反序列化,并且可以轻松地重新序列化为有效的JSON字符串。通常,这意味着它仅包含数据(不包含函数)。这也意味着没有日期,因为JSON没有日期类型(这可能是JSON最痛苦的事情;)

此外,(旁注...)当人们谈论“ JSON对象”时,它们几乎总是表示在顶层具有“大括号”的数据。这很好地对应于javascript对象。但是,JSON规范不要求在JSON字符串的顶层仅存在一个“花括号”对象。在顶层有一个列表,甚至只有一个值都是完全有效的JSON。因此,尽管每个“ JSON对象”都对应于有效的JSON,但并非所有有效的JSON字符串都对应于我们所谓的“ JSON对象”!(因为该字符串可以表示列表或原子值)


5
您的答案有误:在顶层具有原子值的JSON 是无效的。JSON允许top成为对象或数组,但没有别的。标准RFC4627将JSON的语法描述为JSON-text = object / array
罗里·奥肯


5

🔫 JSON:胖的免费替代XML

JSON被人们广泛采用,他们发现使用JSON可以更轻松地生成分布式应用程序和服务。JSON的官方Internet媒体类型是application/json RFC 4627。JSON文件名使用扩展名.json


►JavaScript对象符号(JSON)是一种轻量级的,基于文本的,独立于语言的数据交换格式。JSON已用于在以任何编程语言编写的应用程序之间交换数据。

JSON对象是一个单个对象,其中包含两个函数parse和stringify,用于解析和构造JSON文本。

  • JSON.stringify产生一个符合以下JSON语法的String。
  • JSON.parse接受一个符合JSON语法的字符串。

parseJSON方法将包含在中Fourth Edition of ECMAScript。同时,可以在json.org上获得JavaScript实现。

var objLiteral = {foo: 42}; // JavaScript Object
console.log('Object Literal : ', objLiteral ); // Object {foo: 42}foo: 42__proto__: Object

// This is a JSON String, like what you'd get back from an AJAX request.
var jsonString = '{"foo": 452}';
console.log('JOSN String : ', jsonString ); // {"foo": 452}

// This is how you deserialize that JSON String into an Object.
var serverResposnceObject = JSON.parse( jsonString );
console.log('Converting Ajax response to JavaScript Object : ', serverResposnceObject); // Object {foo: 42}foo: 42 __proto__: Object

// And this is how you serialize an Object into a JSON String.
var serverRequestJSON = JSON.stringify( objLiteral );
console.log('Reqesting server with JSON Data : ', serverRequestJSON); // '{"foo": 452}'

JSON是JavaScript的子集。Javascript源自ECMAScript编程语言标准。


►ECMAScript

ECMAScript已成长为世界上使用最广泛的通用编程语言之一。它是众所周知的嵌入在Web浏览器中的语言,但也已广泛用于服务器和嵌入式应用程序。 ECMAScript基于几种原始技术,最著名的是JavaScript(Netscape Communications)和JScript(Microsoft Corporation)尽管在1994年之前,ECMA被称为“欧洲计算机制造商协会”,但在1994年该组织成为全球性公司之后,由于历史原因保留了“ Ecma”商标。

ECMAScript是该语言,而JavaScript,JScript甚至是ActionScript被称为"Dialects"

方言源于同一语言。它们彼此很相似,因为它们是从相同的语言派生而来,但是它们进行了一些更改。方言是语言本身的一种变体。它源自一种语言。

  • SQL语言-休眠的MySQL方言,Oracle方言等..进行了一些更改或添加了功能。

有关用户浏览器和计算机的信息。

navigator.appName // "Netscape"

ECMAScript是构成JavaScript基础的脚本语言。JavaScript language resources

ECMA-262 Links
Initial Edition, June 1997 PDF.
2nd Edition, August 1998 PDF.
3rd Edition, December 1999 PDF.
5th Edition, December 2009 PDF.
5.1 Edition, June 2011 HTML.
6th Edition, June 2015 HTML.
7ᵗʰ Edition, June 2016 HTML.
8th edition, June 2017 HTML.
9th Edition, 2018 HTML.

注意« 由于工作尚未完成,尚未出版 ECMAScript的第四版


JSON为结构化数据的可移植表示形式定义了一小组格式化规则。

  1. ►键值必须加引号,键只允许使用字符串。如果您使用的不是String,它将转换为String。但不建议使用String以外的其他键。检查像这样的例子- { 'key':'val' }RFC 4627 - jsonformatter

    var storage = {
      0 : null,
      1 : "Hello"
    };
    console.log( storage[1] ); // Hello
    console.log( JSON.stringify( storage ) ); // {"0":null,"1":"Hello","2":"world!"}
    
    var objLiteral = {'key1':'val1'};
        var arr = [10, 20], arr2 = [ 'Yash', 'Sam' ];
        var obj = { k: 'v' }, obj2 = { k2: 'v2' };
        var fun = function keyFun() {} ;
    
    objLiteral[ arr ] = 'ArrayVal';     objLiteral[ arr2 ] = 'OverridenArrayVal';
    objLiteral[ obj ] = 'ObjectVal';    objLiteral[ obj2 ] = 'OverridenObjectVal';
    objLiteral[ fun ] = 'FunctionVal';
    
    console.log( objLiteral );
    // Object {key1: "val1", 10,20: "ArrayVal", Yash,Sam: "OverridenArrayVal", [object Object]: "OverridenObjectVal", function keyFun() {}: "FunctionVal"}
    console.log( JSON.stringify( objLiteral ) );
    // {"key1":"val1","10,20":"ArrayVal","Yash,Sam":"OverridenArrayVal","[object Object]":"OverridenObjectVal","function keyFun() {}":"FunctionVal"}
    console.log( JSON.parse( JSON.stringify( objLiteral ) ) );
    // Object {key1: "val1", 10,20: "ArrayVal", Yash,Sam: "OverridenArrayVal", [object Object]: "OverridenObjectVal", function keyFun() {}: "FunctionVal"}
    
    console.log('Accessing Array  Val : ', objLiteral[ [10,20] ] );
    console.log('Accessing Object Val : ', objLiteral[ '[object Object]' ] );
    console.log('Accessing Function Val : ', objLiteral[ 'function keyFun() {}' ] );
  2. ►JSON字符串必须用“而不是'引起来。字符串非常类似于C或Java字符串。字符串应该用双引号引起来。

    • 文字是您在脚本中实际提供的固定值,而不是变量。
    • 字符串是由零个或多个字符组成的序列,这些字符用反斜杠转义引起来,并使用引号引起来,这与大多数编程语言所用的符号相同。
      • 🔫-字符串中允许使用特殊符号,但不建议使用。
      • \“-特殊字符可以转义。但不建议使用转义(')单引号。在严格模式下,它将引发错误- SyntaxError: Unexpected token ' in JSON

    { "Hai\" \n Team 🔫":5, "Bye \'": 7 }通过在线JSON版本检查此代码。ModesnotStrict,Strinct.

    var jsonString = "{'foo': 452}"; // {'foo': 452}
    var jsonStr = '{"foo": 452}'; // {"foo": 452}
    
    JSON.parse( jsonString ); // Unexpected token ' in JSON at position 1(…)
    JSON.parse( jsonStr ); // Object {foo: 452}
    
    objLiteral['key'] = 'val'; // Object {foo: 42, key: "val"}
    objLiteral.key2 = 'val';
    
    // objLiteral.key\n3 - SyntaxError: Invalid or unexpected token
    objLiteral['key\n3'] = 'val'; // Object {"foo": "42", key: "val", key2: "val", "key↵3": "val"}
    
    JSON.stringify( objLiteral ); // {"foo":"42","key":"val","key2":"val","key\n3":"val"}

对象属性 访问器通过使用点符号或方括号符号提供对对象属性的访问。

  1. ►值的范围更有限(例如,不允许使用任何功能)。值可以是双引号,数字,布尔值,null,对象或数组中的字符串。这些结构可以嵌套。

    var objLiteral = {};
    objLiteral.funKey = function sayHello() {
        console.log('Object Key with function as value - Its outcome message.');
    };
    
    objLiteral['Key'] = 'Val';
    
    console.log('Object Literal Fun : ', objLiteral );
    // Object Literal Fun :  Object {Key: "Val"}Key: "Val"funKey: sayHello()__proto__: Object
    console.log( JSON.stringify( objLiteral ) ); // {"Key":"Val"}

在此处输入图片说明


JavaScript是ECMAScript标准的最受欢迎的实现。Javascript的核心功能基于ECMAScript标准,但是Javascript还具有ECMA规范/标准中未包含的其他附加功能。每个浏览器都有一个JavaScript解释器。

JavaScript是一种动态类型的语言。这意味着在声明变量时不必指定变量的数据类型,并且在脚本执行期间会根据需要自动转换数据类型。

Literals

'37' - 7    // 30
'37' + 7    // "377"
+'37' + 7   // 44
+'37'       // 37
'37'        // "37"

parseInt('37');     // 37
parseInt('3.7');    // 3

parseFloat(3.7);    // 3.7

// An alternative method of retrieving a number from a string is with the + (unary plus) operator:
+'3.7'              // 3.7

Object literals RFC 7159

一个对象结构表示为一对大括号,包围着零个或多个名称/值对(或成员)。名称是一个字符串。每个名称后都有一个冒号,将名称与值分开。单个逗号将值与后面的名称分开。对象中的名称应唯一。

ECMAScript支持基于原型的继承。每个构造函数都有一个关联的原型,并且由该构造函数创建的每个对象都有对其与其构造函数关联的原型(称为对象的原型)的隐式引用。此外,原型可能对其原型具有非null的隐式引用,依此类推;这称为原型链。

通常,在基于类的面向对象语言中,状态由实例承载,方法由类承载,并且继承仅是结构和行为。在ECMAScript中,状态和方法由对象承载,并且结构,行为和状态都被继承。

原型是用于在ECMAScript中实现结构,状态和行为继承的对象。当构造函数创建对象时,该对象隐式引用构造函数的关联原型,以解决属性引用的问题。构造表达式的关联原型可以由程序表达式构造器.prototype引用,添加到对象原型的属性通过继承由共享原型的所有对象共享。


2

对于仍然认为RFC比博客和基于意见的误解更重要的人,让我们尝试回答一些问题。我不会重复前面答案中已经提到的所有正确区别,这里我只是在尝试总结一些关键部分rfc7159的增值

摘自https://tools.ietf.org/html/rfc7159

  1. JavaScript Object Notation(JSON)是用于结构化数据序列化的文本格式。它是从 ECMAScript编程语言标准,第三版[ECMA-262]中定义的JavaScript 对象文字派生的。
  2. JSON可以表示四种原始类型(字符串,数字,布尔值和null)和两种结构化类型(对象和数组)。
  3. 一个对象是零个或多个名称/值对,其中一个名称是字符串的无序集合和一个值是一个字符串,数字,布尔值,null,对象,或阵列。
  4. begin-object = ws%x7B ws; {左花括号
  5. 最终对象 = ws%x7D ws; 右花括号
  6. JSON值必须是对象,数组,数字或字符串,或者是以下三个文字名称之一:false null tr​​ue
  7. 一个对象的结构被表示为一对大括号
  8. 对象中的名称应唯一。 对象 = 开始对象 [成员*(值分隔符成员)] 结束对象
  9. 一个对象的名字都是独特的是在这个意义上,所有的软件实现接收互操作的对象将在名称-值映射一致。当对象中的名称不是唯一的时,接收到该对象的软件的行为是不可预测的。
  10. 示例(来自RFC第12页)

    这是一个JSON对象:

          {
            "Image": {
                "Width":  800,
                "Height": 600,
                "Title":  "View from 15th Floor",
                "Thumbnail": {
                    "Url":    "http://www.example.com/image/481989943",
                    "Height": 125,
                    "Width":  100
                },
                "Animated" : false,
                "IDs": [116, 943, 234, 38793]
              }
          }

    它的Image成员是一个对象,其Thumbnail成员是一个对象,其ID成员是一个数字数组。

确实没有“ JSON对象”之类的东西。

真?


1
Davi,不是Object,而是String。谢谢
abu abu

1

据我了解,主要区别在于灵活性

JSON是“ JavaScript对象表示法”的一种包装,它迫使用户遵循更严格的规则来定义对象。并且它通过限制JavaScript Object Notation功能提供的可能的对象声明方式来做到这一点。

结果,我们有了一个更简单,更标准化的对象,更适合平台之间的数据交换。

因此,基本上,在我上面的示例中,newObject是使用JavaScript Objeect Notation定义的对象;但这不是“有效” JSON对象,因为它不遵循JSON标准要求的规则。

此链接也很有帮助:http : //msdn.microsoft.com/zh-cn/library/bb299886.aspx


2
JSON和对象表示法的用途完全不同:第一个仅用于数据交换,第二个用于创建仅供内部使用的JS对象。它们不是同一事物的严格版本。
ilyo 2012年

0

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

它是与语言无关的数据交换格式。JSON的语法受JavaScript对象文字表示法的启发,但是它们之间存在差异。

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

// JSON:{“ foo”:“ bar”}

//对象文字:var o = {foo:“ bar”}; 引号在JSON上是必需的,因为在JavaScript(更确切地说,在ECMAScript 3rd。Edition中)中,不允许将保留字用作属性名称,例如:

var o = {if:“ foo”}; // ES3中的SyntaxError同时,使用字符串文字作为属性名称(引用属性名称)不会出现任何问题:

var o = {“ if”:“ foo”}; 因此,对于“兼容性”(也许容易评估?),引号是强制性的。

JSON中的数据类型也限制为以下值:

字符串数字对象数组文字为:true false null字符串的语法发生变化。它们必须用双引号分隔,而在JavaScript中,您可以互换使用单引号或双引号。

//无效的JSON:{“ foo”:'bar'}也会改变数字的JSON语法,在JavaScript中,您可以使用十六进制文字,例如0xFF,或(臭名昭著的)八进制文字,例如010。在JSON中,您可以使用仅十进制字面量。

//无效的JSON:{“ foo”:0xFF}


0

Javascript对象文字与JSON:

  • 对象文字语法是创建javascript对象的一种非常方便的方法
  • JSON语言代表“ Javascript对象表示法”,其语法派生自javascript对象文字语法。它用作与编程语言无关的文本数据传输格式。

例:

JS对象表示法,在JS中用于方便地在代码中创建对象:

const JS_Object = {
  1: 2,  // the key here is the number 1, the value is the number 2
  a: 'b', // the key is the string a, the value is the string b
  func: function () { console.log('hi') }
  // the key is func, the value is the function
}

JSON范例:

{"widget": {
    "debug": "on",
    "window": {
        "title": "Sample Konfabulator Widget",
        "name": "main_window",
        "width": 500,
        "height": 500
    },
    "image": { 
        "src": "Images/Sun.png",
        "name": "sun1",
        "hOffset": 250,
        "vOffset": 250,
        "alignment": "center"
    },
    "text": {
        "data": "Click Here",
        "size": 36,
        "style": "bold",
        "name": "text1",
        "hOffset": 250,
        "vOffset": 100,
        "alignment": "center",
        "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
    }
}}

主要区别:

  • JSON中的所有对象键都必须是字符串。在Javascript对象中,键可以是字符串或数字

  • JSON中的所有字符串都必须用“双引号”引起来。而在Javascript中,单引号和双引号均允许。即使Javascript对象表示法中没有引号,对象键也隐式转换为字符串。

  • 在JSON中,不能将函数定义为对象的值(因为它是Java特定的)。在Javascript中,这是完全合法的。

Javascript内置JSON对象:

JSON使用JSONJavascript在其运行时中提供的内置对象,可以轻松地将对象转换为Javascript,反之亦然。例如:

const Object = {
  property1: true,
  property2: false,
}; // creating object with JS object literal syntax

const JSON_object = JSON.stringify(Object);  // stringify JS object to a JSON string

console.log(JSON_object); // note that the (string) keys are in double quotes

const JS_object = JSON.parse(JSON_object);  // parse JSON string to JS object

console.log(JS_object.property1, JS_object.property2); 
// accessing keys of the newly created object


0

这是一个令人惊讶的区别:您不能undefined在json中使用,并且所有具有未定义值的对象字段在JSON.stringify

let object =  { "a": undefined } ;

let badJSON= '{ "a": undefined }';


console.log('valid JS object :', object );
console.log('JSON from object:', JSON.stringify(object) );
console.log('invalid json    :', JSON.parse(badJSON) );

🙈🙉🙊

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.