JSON 和 Object Literal Notation 有什么区别?

IT技术 javascript json object-notation
2020-12-15 23:40:05

有人能告诉我使用Object Literal NotationJSON object定义的 JavaScript 对象之间的主要区别是什么吗?

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

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

为什么在这种情况下它不是 JSON 对象?仅仅因为它不是用引号定义的吗?

6个回答

让我们首先澄清JSON到底什么JSON 是一种文本的、与语言无关的数据交换格式,很像 XML、CSV 或 YAML。

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

此类格式通常与语言无关,这意味着它们可以由 Java、Python、JavaScript、PHP 处理,等等。

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

作为一个反例,Python 有tuples的概念,它们的语法是(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 源代码,而不是处理string,那么您就不是在处理 JSON。也许您收到的数据是 JSON(例如,通过 ajax 或从文件中读取),但是一旦您或您正在使用的库解析了它,它就不再是 JSON。


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

对象字面量中的键始终是字符串,无论您是否使用“”。
2021-02-12 23:40:05
可能值得注意的是,通常您希望在注释合法且 JSON 规范不允许注释的上下文中使用 JavaScript 对象字面量(请参阅这篇文章.
2021-02-23 23:40:05
@overexchange:“对象文字中的键总是字符串”你在这里混合了两件事,但我不能责怪你,因为我也没有在这里划清界限。您必须区分对象文字和对象一个文字是你在源代码中写的字符序列。是通过解释源代码创建的。对象文字(语法)允许您使用标识符名称字符串文字数字文字你是对的,在运行时,这些都被转换为字符串(但我们现在也有符号)。
2021-02-27 23:40:05
@SeanKinsey:除了它不是:timelessrepo.com/json-isnt-a-javascript-subset
2021-03-04 23:40:05
另请注意,JSON 是Object Literal Notation 的一个子集
2021-03-06 23:40:05

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

  • 必须引用键值
  • 字符串必须用"和 不'
  • 您的值范围更有限(例如,不允许使用任何函数)
喜欢这个“不允许使用功能”。
2021-02-11 23:40:05
也不允许评论。出于可疑的原因。(听说他们被问过几次。)这是我要说的主要区别。
2021-02-16 23:40:05

真的没有“JSON 对象”这样的东西。

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

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

您的答案中有一个错误:在顶级具有原子值无效的JSON。JSON 允许顶部是一个对象或一个数组,但没有别的。标准RFC4627将 JSON 的语法描述为JSON-text = object / array.
2021-03-07 23:40:05

根据JavaScript 中的 JSON

JSON 是JavaScript 的对象字面量表示法的一个子集

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

除了阅读文档,正如@Filix King 建议的那样,我还建议使用JSONLint 在线 JSON 验证器这就是我如何了解到 JSON 对象的键必须是字符串。

请注意:它不是一个精确的子集,有一些 JSON 字符串作为 JS 对象文字无效
2021-03-05 23:40:05

🔫 JSON:XML 的无脂肪替代方案

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


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

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

  • JSON.stringify 生成符合以下 JSON 语法的字符串。
  • 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 已经成长为世界上使用最广泛的通用编程语言之一。它以嵌入在 Web 浏览器中的语言而闻名,但也被广泛用于服务器和嵌入式应用程序。 ECMAScript 基于多种原始技术,最著名的是JavaScript(Netscape Communications))和JScript(Microsoft Corporation)。)虽然在 1994 年之前,ECMA 被称为“欧洲计算机制造商协会”,但在 1994 年之后,当该组织全球化时,由于历史原因,“商标”“Ecma”被保留了下来。

ECMAScript 是一种语言,而 JavaScript、JScript 甚至 ActionScript 被称为"Dialects".

方言起源于同一种语言。它们彼此非常相似,因为它们源自相同的语言,但它们发生了一些变化。方言是语言本身的变体。它源自单一语言。

  • SQL 语言 - Hibernate 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 的第 4 版没有发布,因为工作不完整


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 版本检查此代码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"}
    

在此处输入图片说明


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

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

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