根本没有“JSON 对象”这回事!

前言

写这篇文章的目的是经常看到开发人员说:把字符串转化为 JSON 对象,把 JSON 对象转化成字符串等类似的话题,所以把之前收藏的一篇老外的文章整理翻译了一下,供大家讨论,如有错误,请大家指出,多谢。

正文

本文的主题是基于 ECMAScript262-3 来写的,2011 年的 262-5 新规范增加了 JSON 对象,和我们平时所说的 JSON 有关系,但是不是同一个东西,文章最后一节会讲到新增加的 JSON 对象。

我想给大家澄清一下一个非常普遍的误解,我认为很多 JavaScript 开发人员都错误地把 JavaScript 对象字面量(Object Literals)称为 JSON 对象(JSON Objects),因为他的语法和JSON规范里描述的一样,但是该规范里也明确地说了 JSON 只是一个数据交换语言,只有我们将之用在 string 上下文的时候它才叫 JSON。

序列化与反序列化

2 个程序(或服务器、语言等)需要交互通信的时候,他们倾向于使用 string 字符串因为 string 在很多语言里解析的方式都差不多。复杂的数据结构经常需要用到,并且通过各种各样的中括号{},小括号(),叫括号<>和空格来组成,这个字符串仅仅是按照要求规范好的字符。

为此,我们为了描述这些复杂的数据结构作为一个 string 字符串,制定了标准的规则和语法。JSON 只是其中一种语法,它可以在 string 上下文里描述对象,数组,字符串,数字,布尔型和 null,然后通过程序间传输,并且反序列化成所需要的格式。YAML 和XML(甚至 request params)也是流行的数据交换格式,但是,我们喜欢 JSON,谁叫我们是 JavaScript 开发人员呢!

字面量

引用 Mozilla Developer Center 里的几句话,供大家参考:

  1. 他们是固定的值,不是变量,让你从“字面上”理解脚本。 (Literals)
  2. 字符串字面量是由双引号(")或单引号(')包围起来的零个或多个字符组成的。(Strings Literals)
  3. 对象字面量是由大括号({})括起来的零个或多个对象的属性名-值对。(Object Literals)

何时是 JSON,何时不是 JSON?

JSON 是设计成描述数据交换格式的,他也有自己的语法,这个语法是 JavaScript 的一个子集。 { "prop": "val" } 这样的声明有可能是 JavaScript 对象字面量也有可能是 JSON 字符串,取决于什么上下文使用它,如果是用在 string 上下文(用单引号或双引号引住,或者从 text 文件读取)的话,那它就是 JSON 字符串,如果是用在对象字面量上下文中,那它就是对象字面量。

// 这是JSON字符串
var foo = '{ "prop": "val" }';
// 这是对象字面量
var bar = { "prop": "val" };

而且要注意,JSON 有非常严格的语法,在 string 上下文里{ "prop": "val" } 是个合法的 JSON,但{ prop: "val" }和{ 'prop': 'val' }却是不合法的。所有属性名称和它的值都必须用双引号引住,不能使用单引号。另外,即便你用了转义以后的单引号也是不合法的,详细的语法规则可以到这里查看

放到上下文里来看

大家伙可能嗤之以鼻:难道 JavaScript 代码不是一个大的字符串?

当然是,所有的 JavaScrip t代码和 HTML(可能还有其他东西)都是字符串,直到浏览器对他们进行解析。这时候 .jf 文件或者 inline 的 JavaScript 代码已经不是字符串了,而是被当成真正的 JavaScript 源代码了,就像页面里的 innterHTML 一样,这时候也不是字符串了,而是被解析成 DOM 结构了。

再次说一下,这取决于上下文,在 string 上下文里使用带有大括号的 JavaScript 对象,那它就是 JSON 字符串,而如果在对象字面量上下文里使用的话,那它就是对象字面量。

真正的 JSON 对象

开头已经提到,对象字面量不是 JSON 对象,但是有真正的 JSON 对象。但是两者完全不一样概念,在新版的浏览器里 JSON 对象已经被原生的内置对象了,目前有 2 个静态方法:JSON.parse 用来将 JSON 字符串反序列化成对象,JSON.stringify 用来将对象序列化成 JSON 字符串。老版本的浏览器不支持这个对象,但你可以通过 json2.js 来实现同样的功能。

如果还不理解,别担心,参考一下的例子就知道了:

// 这是JSON字符串,比如从AJAX获取字符串信息
var my_json_string = '{ "prop": "val" }';
// 将字符串反序列化成对象
var my_obj = JSON.parse( my_json_string );
alert( my_obj.prop == 'val' ); // 提示 true, 和想象的一样!
// 将对象序列化成JSON字符串
var my_other_json_string = JSON.stringify( my_obj );

另外,Paul Irish提到 Douglas Crockford 在 JSON RFC里用到了“JSON object”,但是在那个上下文里,他的意思是“对象描述成 JSON 字符串”不是“对象字面量”。

更多资料

如果你想了解更多关于 JSON 的资料,下面的连接对你绝对有用:

深入理解 JavaScript(五)的更多相关文章

  1. 深入理解JavaScript的闭包特性如何给循环中的对象添加事件

    初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...

  2. 深入理解javascript原型和闭包(13)-【作用域】和【上下文环境】

    上文简单介绍了作用域,本文把作用域和上下文环境结合起来说一下,会理解的更深一些. 如上图,我们在上文中已经介绍了,除了全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了.而不 ...

  3. 深入理解javascript原型和闭包(15)——闭包

    前面提到的上下文环境和作用域的知识,除了了解这些知识之外,还是理解闭包的基础. 至于“闭包”这个词的概念的文字描述,确实不好解释,我看过很多遍,但是现在还是记不住. 但是你只需要知道应用的两种情况即可 ...

  4. 深入理解javascript原型和闭包(18)——补充:上下文环境和作用域的关系

    本系列用了大量的篇幅讲解了上下文环境和作用域,有些人反映这两个是一回儿事.本文就用一个小例子来说明一下,作用域和上下文环境绝对不是一回事儿. 再说明之前,咱们先用简单的语言来概括一下这两个的区别. 0 ...

  5. 【转】深入理解JavaScript闭包闭包(closure) (closure)

    一.什么是闭包?"官方"的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述 ...

  6. 深入理解javascript作用域系列第一篇——内部原理

    × 目录 [1]编译 [2]执行 [3]查询[4]嵌套[5]异常[6]原理 前面的话 javascript拥有一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则被称为作用域.作用域 ...

  7. 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点

    深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 2011-12-28 23:00 by 汤姆大叔, 139489 阅读, 119 评论, 收藏, 编辑 才华横溢的 ...

  8. 深入理解JavaScript中创建对象模式的演变(原型)

    深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...

  9. 深入理解Javascript面向对象编程

    深入理解Javascript面向对象编程 阅读目录 一:理解构造函数原型(prototype)机制 二:理解原型域链的概念 三:理解原型继承机制 四:理解使用类继承(继承的更好的方案) 五:建议使用封 ...

  10. (转)深入理解javascript的function

    原文:http://www.cnblogs.com/sharpxiajun/archive/2011/09/16/2179323.html javascript笔记:深入理解javascript的fu ...

随机推荐

  1. 【Docker 命令】- pause/unpause 命令

    docker pause :暂停容器中所有的进程. docker unpause:恢复容器中所有的进程. 语法 docker pause [OPTIONS] CONTAINER [CONTAINER. ...

  2. 异步执行任务SimpleAsyncTaskExecutor详解

    SimpleAsyncTaskExecutor 异步执行用户任务的SimpleAsyncTaskExecutor.每次执行客户提交给它的任务时,它会启动新的线程,并允许开发者控制并发线程的上限(con ...

  3. 前端基础:JavaScript介绍

    JavaScript介绍 一.JavaScript简介 1.在1995年时,由Netscape公司的Brendan Eich,在网景导航者浏览器上首次设计实现二层,因为Netscape与Sun合作,N ...

  4. [洛谷P4980]【模板】Polya定理

    题目大意:给一个$n$个点的环染色,有$n$中颜色,问有多少种涂色方案是的旋转后本质不同 题解:$burnside$引理:$ans=\dfrac1{|G|}\sum\limits_{g\in G}A_ ...

  5. BZOJ1499:[NOI2005]瑰丽华尔兹——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1499 舞厅是一个N行M列的矩阵,矩阵中的某些方格上堆放了一些家具,其他的则是空地.钢琴可以在空地上滑 ...

  6. 洛谷3690:【模板】Link Cut Tree——题解

    https://www.luogu.org/problemnew/show/P3690 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...

  7. HDU.1233 还是畅通工程(Prim)

    HDU.1233 还是畅通工程(Prim) 题意分析 首先给出n,代表村庄的个数 然后出n*(n-1)/2个信息,每个信息包括村庄的起点,终点,距离, 要求求出最小生成树的权值之和. 注意村庄的编号从 ...

  8. jQuery获取元素对象本身的html

    Jquery获取html标签,包含该标签本身 2018年04月01日 20:16:10 清--水 阅读数:829   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.c ...

  9. 题解【bzoj2427 [HAOI2010]软件安装】

    Description 现在我们的手头有\(N\)个软件,对于一个软件\(i\),它要占用\(W_i\)的磁盘空间,它的价值为\(V_i\).我们希望从中选择一些软件安装到一台磁盘容量为\(M\)计算 ...

  10. c# 深拷贝与浅拷贝的区别分析及实例

    浅拷贝(影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用. 深拷贝(深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.就是说完全是新对象产生的. 深拷贝是指源对象与拷贝对象互相独 ...