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

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

根据JavaScript书籍,它说这是一个使用对象表示法定义的对象:

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

为什么这里不是JSON对象?仅仅因为它不是用引号定义的吗?

75321 次浏览

让我们首先澄清JSON < em > < / em >实际上是什么。JSON是一种文本,独立于语言的数据交换格式,很像XML、CSV或YAML。

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

这些格式通常是独立于语言的,这意味着它们可以被Java、Python、JavaScript、PHP等等处理。

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

作为一个反例,Python有元组的概念,它们的语法是(x, y)。JavaScript没有这样的东西。


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

JSON有以下语法约束:

  • 对象必须是字符串(即用双引号"括起来的字符序列)。
  • 取值为:
    • 一个字符串
    • 一个数字
    • 一个JSON对象
    • 一个数组
    • true
    • false
    • null
    • 李< / ul > < / >
    • 重复键({"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对象

JSON有更有限的语法,包括:

  • 关键值必须加引号
  • 字符串必须以"而不是'作为引号
  • 你有一个更有限的值范围(例如不允许函数)

据我所知,主要的区别是< em > < / em >灵活性

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

因此,我们有一个更简单、更标准化的对象,更适合于平台之间的数据交换。

基本上,上面例子中的newObject是一个使用JavaScript object Notation定义的对象;但它不是一个“有效的”JSON对象,因为它不遵循JSON标准要求的规则。

这个链接也很有帮助: http://msdn.microsoft.com/en-us/library/bb299886.aspx < / p >

根据JavaScript JSON

JSON是对象的子集

换句话说,有效的JSON也是有效的JavaScript对象文字表示法,但不一定是相反。

除了像@Filix King建议的那样阅读文档之外,我还建议使用JSONLint在线JSON验证器。这就是为什么我知道JSON对象的键必须是字符串。

实际上没有所谓的“JSON对象”。

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

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

对于那些仍然认为RFC比博客和基于观点的误解更重要的人,让我们试着回答澄清一些观点。 我不会重复之前的答案中已经提到的所有正确的差异,这里我只是试图增加价值,总结一些关键部分rfc7159

https://www.rfc-editor.org/rfc/rfc7159的摘录

    对象 Notation (JSON)是一种文本格式 结构化数据的序列化。它派生自对象 JavaScript的字面量,在ECMAScript编程中定义 语言标准,第三版[ECMA-262].

    JSON可以表示四种基本类型(字符串,数字,布尔值, 和null)和两个结构化类型(对象和数组) 对象是零个或多个名称/值的无序集合 对,其中名称是字符串,值是字符串,number,

    . boolean, null, 对象或数组
  1. begin-object = ws %x7B ws;{左花括号

  2. end-object = ws %x7D ws;}右花括号

  3. JSON值必须是对象、数组、数字、字符串或其中之一 以下三个字面值:false、null、true

  4. 对象结构体用一对花括号表示

  5. 对象中的名称必须是唯一的。 对象 = begin-object[成员*(值分隔符成员)] end-object < / >强

    对象的名字都是唯一的,在这个意义上是可互操作的 所有接受对象的软件实现都会同意 名称-值映射。当对象中的名称不是 唯一的,接收这样对象的软件的行为是 不可预测的。< / p >
  6. 示例(来自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成员是对象

实际上没有“JSON对象”这样的东西。

真的吗?

🔫JSON: XML的无脂肪替代品

JSON已被人们广泛采用,人们发现它使生成分布式应用程序和服务变得更加容易。JSON的官方互联网媒体类型是application/json RFC 4627。JSON文件名使用扩展名.json


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

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

  • JSON。stringify生成符合以下JSON语法的String。
  • JSON。parse接受一个符合JSON语法的String。

parseJSON方法将包含在Fourth Edition of ECMAScript. xml中。与此同时,JavaScript实现可以在json.org上找到。

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基于几种原始技术,最著名的是__ABC0(网景通信))和JScript(微软公司)虽然在1994年之前,ECMA被称为“欧洲计算机制造商协会”,但在1994年之后,当该组织成为全球性组织时,“商标”被称为“欧洲计算机制造商协会”。“Ecma"因为历史原因被保留。

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

各种方言都起源于同一种语言。它们彼此非常相似,因为它们起源于同一种语言,但它们经历了一些变化。 方言是一种语言本身的变体。

  • SQL语言- Hibernate MySQL方言,Oracle方言,..它们有一些变化或增加的功能。

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

navigator.appName // "Netscape"

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

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

注意« ECMAScript的第四版而不是因为作品不完整而出版


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

  1. ►键值必须用引号括起来,键只允许使用字符串。如果你使用其他字符串,它将转换为字符串。但不建议使用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. 字符串必须用"而不是‘。字符串非常类似于C或Java字符串。字符串应该用双引号括起来。

  • 文字是固定的值,而不是变量,您可以在脚本中逐字提供。
  • 字符串是由0个或多个字符组成的序列,用带有反斜杠擒纵的引号括起来,与大多数编程语言中使用的符号相同。
  • 🔫-字符串中允许使用特殊符号,但不建议使用。
  • <李>“—特殊字符支持转义。但不建议使用转义(')单引号。 在严格模式下,它将抛出Error - SyntaxError: Unexpected token ' in JSON

通过在线JSON版本检查此代码{ "Hai\" \n Team 🔫":5, "Bye \'": 7 }Modes notStrict, 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. 你有一个更有限的值范围(例如不允许函数)。值可以是双引号字符串、数字、布尔值、空值、对象或数组。这些结构可以嵌套。

     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"}
    

enter image description here


JavaScript是ECMAScript标准最流行的实现。 Javascript的核心特性是基于ECMAScript标准的,但是Javascript还有其他ECMA规范/标准中没有的附加特性。每个浏览器都有一个JavaScript解释器。 < / em > < / p >

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 < em > RFC 7159 < / em >

一个对象结构用一对花括号表示,括号中包含0个或多个名称/值对(或成员)。名字就是 字符串。每个名称后面都有一个冒号,将名称与值分开。一个逗号将值与后面的字符分隔开 的名字。

.对象中的名称必须是唯一的 ECMAScript支持基于原型的继承。每个构造函数都有一个相关联的原型,由该构造函数创建的每个对象都有一个对原型的隐式引用(称为对象的原型) 原型)与其构造函数相关联。此外,原型可能有对其原型的非空隐式引用,等等;这被称为原型链

.

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

原型是ECMAScript中用于实现结构、状态和行为继承的对象。当构造函数创建对象时,该对象隐式引用构造函数的关联原型,以解析属性引用。构造函数的关联原型可以 由程序表达式构造函数引用。

.原型和添加到对象原型中的属性通过继承被共享该原型的所有对象共享

首先你应该知道JSON是什么:

这是语言无关的数据交换格式。 JSON的语法受到JavaScript Object Literal表示法的启发,但它们之间存在差异

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

< p > / / JSON: {"foo": "bar"}

//对象文字: Var o = {foo: "bar"}; 引号在JSON中是强制的,因为在JavaScript中(更确切地说在ECMAScript 3rd中)。版本),不允许使用保留字作为属性名,例如:

var o = {if: "foo"};// ES3中的SyntaxError 而使用字符串文字作为属性名(引用属性名)则没有问题:

var o = {"if": "foo"}; 所以为了“兼容性”(和容易评估可能?)引号是强制性的

JSON中的数据类型也仅限于以下值:

< p >字符串 数量 对象 数组 字面意思为: 真正的 假 零 字符串的语法改变了。它们必须用双引号分隔,而在JavaScript中,你可以交替使用单引号或双引号

//无效JSON: {"foo": 'bar'} 数字的公认JSON语法也会发生变化,在JavaScript中,你可以使用十六进制文字,例如0xFF,或(臭名昭著的)八进制文字,例如010。在JSON中,你只能使用十进制文字

//无效JSON: {"foo": 0xFF}

. {"foo": 0xFF

Javascript对象文字vs 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中,函数不能定义为对象的值(因为这是特定于Javascript的)。在Javascript中,这是完全合法的。

Javascript在JSON对象中构建:

JSON对象可以很容易地转换为Javascript,反之亦然,使用Javascript在其运行时提供的内置JSON对象。例如:

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

这里有一个令人惊讶的区别:你不能在json中使用undefined,所有具有未定义值的对象字段将在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) );

🙈🙉🙊