JSON和Object Literal Notation有什么区别?
有人能告诉我什么是通过使用“对象文字符号”和JSON对象定义的JavaScript对象之间的主要区别?
根据一本JavaScript书,它说这是一个使用Object Notation定义的对象 :
var anObject = { property1 : true, showMessage : function (msg) { alert(msg) } };
为什么不是这种情况下的JSON对象? 只是因为它没有使用引号定义?
让我们先澄清一下JSON实际上是什么。 JSON是一种文本的 ,语言无关的数据交换格式,非常像XML,CSV或YAML。
数据可以以多种方式存储,但是如果应该将其存储在文本文件中并且可以被计算机读取,则需要遵循一些结构。 JSON是定义这种结构的多种格式之一。
这样的格式通常是独立于语言的,这意味着它们可以通过Java,Python,JavaScript,PHP来处理。
相反, JavaScript是一种编程语言。 当然JavaScript也提供了一种定义/描述数据的方式,但是这个语法对于JavaScript来说是非常特殊的。
作为一个反例,Python具有元组的概念,它们的语法是(x, y)
。 JavaScript没有这样的东西。
让我们看看JSON和JavaScript对象文字之间的语法差异。
JSON具有以下语法约束:
- 对象键必须是string (即用双引号括起来的字符序列)。
- 值可以是:
- 一个string
- 一个号码
- 一个(JSON)对象
- 数组
-
true
-
false
-
null
- 重复键(
{"foo":"bar","foo":"baz"}
)会产生未定义的特定于实现的结果; JSON规范特别没有定义它们的语义
在JavaScript中,对象文字可以有
- string文字,数字文字或标识符名称作为关键字(因为ES6,键现在也可以计算,这引入了另一种语法)。
- 这些值可以是任何有效的JavaScriptexpression式,包括函数定义和
undefined
。 - 重复键生成定义的指定结果(松散模式下,后者定义replace前者;在严格模式下,这是错误的)。
知道,只是看语法 ,你的例子不是JSON,因为两个原因:
- 您的密钥不是string(文字)。 他们是标识符名称 。
- 你不能把一个函数作为一个值赋给一个“JSON对象”(因为JSON没有为函数定义任何语法)。
但最重要的是,从一开始就重复我的解释:您处于JavaScript环境中。 您定义一个JavaScript对象。 如果有的话,一个“JSON对象”只能包含在一个string中:
var obj = {foo: 42}; // creates a JavaScript object var json = '{"foo": 452}'; // creates a string containing JSON
也就是说,如果您正在编写JavaScript源代码,而不是处理string ,那么您不会处理JSON。 也许你收到的数据作为JSON(例如,通过ajax或从文件中读取),但是一旦你或者你正在使用的库已经parsing它,它不再是JSON。
只是因为对象文字和JSON看起来相似 ,并不意味着你可以互换地命名它们。 另请参见没有“JSON对象”这样的事情 。
JSON有一个更有限的语法,包括:
- 关键值必须被引用
- string必须用
"
而不是'
- 你有一个更有限的值范围(例如,没有允许的function)
真的没有“JSON对象”这样的东西。
JSON规范是将数据编码为string的语法。 人们称之为“JSON对象”(在JavaScript中)实际上只是一个普通的JavaScript对象,可能已经(可能)从一个有效的JSONstring中被反序列化,并且可以被轻易地重新序列化为一个有效的JSONstring。 这通常意味着它只包含数据(而不是函数)。 这也意味着没有date,因为JSON没有datetypes(可能是关于JSON最痛苦的事情;)
此外,当人们谈论“JSON对象”时,他们几乎总是指在顶层具有“花括号”的数据。 这很好地对应于一个javascript对象。 但是,JSON规范并不要求在JSONstring的顶层有一个“花括号”对象。 在顶层有一个列表,甚至只有一个值,这是完全有效的JSON。 所以,虽然每个“JSON对象”对应于有效的JSON,但并不是所有有效的JSONstring都对应于我们所说的“JSON对象”! (因为string可能代表一个列表或一个primefaces值)
根据JavaScript中的JSON ,
JSON是JavaScript对象文字符号的一个子集 。
换句话说,有效的JSON也是有效的JavaScript对象文字符号,但不一定是相反的方式。
除了阅读文档 ,@Filix Kingbuild议,我还build议玩JSONLint在线JSONvalidation 。 这就是我得知JSON对象的键必须是string。
据我所知,主要的区别是灵活性 。
JSON是一种“JavaScript Object Notation”的包装,它强制用户遵守更严格的定义对象的规则。 而且它通过限制JavaScript对象表示法提供的可能的对象声明方法来实现这一点。
因此,我们有了一个更加简单和更加标准化的对象,更适合平台之间的数据交换。
所以基本上,在我上面的例子中的newObject是一个使用JavaScript Objeect Notation定义的对象; 但它不是“有效的”JSON对象,因为它不遵循JSON标准所要求的规则。
这个链接也很有帮助: http : //msdn.microsoft.com/en-us/library/bb299886.aspx
对于那些仍然认为RFC比博客更重要和基于观点的误解的人,让我们试着澄清一些观点。 我不打算重复在前面的答案中已经提到的所有正确的区别,在这里我只是想增加值总结一些关键部分rfc7159
摘自https://tools.ietf.org/html/rfc7159
- JavaScript 对象表示法(JSON)是用于结构化数据序列化的文本格式。 它来源于ECMAScript编程语言标准第三版[ECMA-262]中定义的JavaScript 对象文字。
- JSON可以表示四种基本types(string,数字,布尔值和空值)以及两种结构化types( 对象和数组)。
- 对象是零个或多个名称/值对的无序集合,其中名称是string,值是string,数字,布尔值,空值, 对象或数组。
- begin-object = ws%x7B ws; {左大括号
- end-object = ws%x7D ws; }右括号
- JSON值必须是对象 ,数组,数字或string,或者是以下三个文字名称之一:false null true
- 一个对象结构被表示为一对大括号
- 对象内的名字应该是唯一的。 object = begin-object [member *(value-separator member)] end-object
- 所有名称都是唯一的对象是可互操作的,因为所有接收该对象的软件实现将同意名称 – 值映射。 当对象中的名称不唯一时,接收这样的对象的软件的行为是不可预知的。
-
示例(从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成员是一个对象,其缩略图成员是一个对象 ,其IDs成员是一个数组数组。
真的没有“JSON对象”这样的东西。
真?
JSON :XML的无脂替代品
JSON被广泛采用的人发现,它使得生产分布式应用程序和服务变得更容易。 JSON的官方Internet媒体types是application/json
RFC 4627
。 JSON文件名使用扩展名.json
。
►JavaScript对象表示法( JSON
)是一种轻量级,基于文本的,与语言无关的数据交换格式。 JSON已被用于在用任何编程语言编写的应用程序之间交换数据。
JSON对象是包含两个函数parse和stringify的单个对象,用于parsing和构buildJSON文本。
- JSON.stringify产生一个符合以下JSON语法的string。
- JSON.parse接受一个符合JSON语法的string。
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已经发展成为世界上使用最广泛的通用编程语言之一。 它被称为embedded在网页浏览器中的语言,但也被广泛用于服务器和embedded式应用程序。 ECMAScript基于几种原始技术,最着名的是JavaScript
(Netscape Communications)和JScript
(Microsoft Corporation) 。 虽然在1994年之前,ECMA被称为“欧洲计算机制造商协会”,1994年后,当组织成为全球性时,“商标”“Ecma”由于历史原因而被保留。
ECMAScript是语言,而JavaScript,JScript甚至ActionScript都被称为"Dialects"
。
方言来源于同一种语言。 他们是相似的,因为他们是从相同的语言衍生出来的,但他们已经发生了一些变化。 方言是语言本身的变体。 它来源于单一的语言。
- SQL语言 – hibernateMySQL方言,Oracle方言,..有一些变化或增加function。
有关您的用户的浏览器和计算机的信息。
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 第4版未发布,因为作品不完整 。
JSON为结构化数据的可移植表示定义了一小组格式化规则。
-
►键值必须被引用,只有键允许使用string。 如果使用其他string,它将转换为string。 但不build议使用string以外的其他键。 通过
RFC 4627 - jsonformatter
查看一个像这样的示例 –{ '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() {}' ] );
-
►JSONstring必须用“and not”引用,string非常类似于C或Javastring, string应该用双引号括起来。
- 文字是固定的值,而不是variables,你从字面上提供你的脚本。
- string是用反斜杠擒纵符引用的零个或多个字符的序列,在大多数编程语言中使用相同的符号。
- String – 特殊符号允许在string中,但不build议使用。
- \“ – 特殊字符可以被转义,但是不推荐(')单引号。在严格模式下,它会
SyntaxError: Unexpected token ' in JSON
抛出错误 –SyntaxError: Unexpected token ' in JSON
用这个代码
{ "Hai\" \n Team 🔫":5, "Bye \'": 7 }
通过在线的JSON Editing进行检查。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"}
对象属性访问器通过使用点符号或括号符号来提供对对象属性的访问。
-
►您的值范围更有限(例如,不允许使用任何function)。 值可以是双引号,数字,布尔值,空值,对象或数组中的string。 这些结构可以嵌套。
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标准最stream行的实现。 Javascript的核心function基于ECMAScript标准,但Javascript还有其他附加function,不在ECMA规范/标准中。 每个浏览器都有一个JavaScript解释器。
JavaScript是一种dynamictypes的语言。 这意味着您在声明variables时不必指定variables的数据types,并且在脚本执行期间根据需要自动转换数据types。
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
对象结构被表示为围绕零个或多个名称/值对(或成员)的一对大括号。 名称是一个string。 每个名称后面都有一个冒号,将名称与值分开。 一个逗号与下面的名字分开一个值。 对象内的名字应该是唯一的。
ECMAScript支持基于原型的inheritance。 每个构造函数都有一个关联的原型,并且由该构造函数创build的每个对象都对与其构造函数关联的原型(称为对象原型)有一个隐式引用。 此外,原型可能会有一个非空的隐式引用其原型,等等。 这被称为原型链。
在一个基于类的面向对象语言中,一般情况下,状态由实例承载,方法由类承载,而inheritance只是结构和行为。 在ECMAScript中,状态和方法由对象携带,结构,行为和状态都被inheritance。
原型是用于在ECMAScript中实现结构,状态和行为inheritance的对象。 当构造函数创build一个对象时,为了parsing属性引用,该对象隐含地引用了构造函数的关联原型。 构造函数的关联原型可以被程序expression式constructor.prototype引用,添加到对象原型的属性通过inheritance来共享原型。