深入理解JavaScript系列(9) 根本没有“JSON对象”这回事!


Posted in Javascript onJanuary 15, 2012

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

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

英文原文:http://benalman.com/news/2010/03/theres-no-such-thing-as-a-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里的几句话,供大家参考:

他们是固定的值,不是变量,让你从“字面上”理解脚本。 (Literals)
字符串字面量是由双引号(")或单引号(')包围起来的零个或多个字符组成的。(Strings Literals)
对象字面量是由大括号({})括起来的零个或多个对象的属性名-值对。(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代码不是一个大的字符串?

当然是,所有的JavaScript代码和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的资料,下面的连接对你绝对有用:

  • JSON specification
  • JSON RFC
  • JSON on Wikipedia
  • JSONLint - The JSON Validator
  • JSON is not the same as JSON
Javascript 相关文章推荐
Javascript的IE和Firefox兼容性汇编(zz)
Feb 02 Javascript
JS 两日期相减,获得天数的小例子(兼容IE,FF)
Jul 01 Javascript
js禁止回车提交表单的示例代码
Dec 23 Javascript
JavaScript中string对象
Jun 12 Javascript
jquery 中ajax执行的优先级
Jun 22 Javascript
javascript日期计算实例分析
Jun 29 Javascript
js中 javascript:void(0) 用法详解
Aug 11 Javascript
JQuery核心函数是什么及使用方法介绍
May 03 Javascript
浅谈vue的踩坑路
Aug 31 Javascript
three.js实现3D模型展示的示例代码
Dec 31 Javascript
4个顶级开源JavaScript图表库
Sep 29 Javascript
vue实现购物车小案例
Sep 27 Javascript
深入理解JavaScript系列(8) S.O.L.I.D五大原则之里氏替换原则LSP
Jan 15 #Javascript
深入理解JavaScript系列(7) S.O.L.I.D五大原则之开闭原则OCP
Jan 15 #Javascript
深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP
Jan 15 #Javascript
深入理解JavaScript系列(6) 强大的原型和原型链
Jan 15 #Javascript
深入理解JavaScript系列(4) 立即调用的函数表达式
Jan 15 #Javascript
深入理解JavaScript系列(3) 全面解析Module模式
Jan 15 #Javascript
深入理解JavaScript系列(2) 揭秘命名函数表达式
Jan 15 #Javascript
You might like
PHP中uploaded_files函数使用方法详解
2011/03/09 PHP
php递归函数中使用return的注意事项
2014/01/17 PHP
PHP函数addslashes和mysql_real_escape_string的区别
2014/04/22 PHP
destoon在360浏览器下出现用户被强行注销的解决方法
2014/06/26 PHP
PHP实现git部署的方法教程
2017/12/19 PHP
解决tp5在nginx下修改配置访问的问题
2019/10/16 PHP
event对象的方法 兼容多浏览器
2009/06/27 Javascript
详解JavaScript中setSeconds()方法的使用
2015/06/11 Javascript
JavaScript的RequireJS库入门指南
2015/07/01 Javascript
纯js实现图片匀速淡入淡出效果
2017/08/22 Javascript
微信小程序列表渲染功能之列表下拉刷新及上拉加载的实现方法分析
2017/11/27 Javascript
微信小程序ajax实现请求服务器数据及模版遍历数据功能示例
2017/12/15 Javascript
父组件中vuex方法更新state子组件不能及时更新并渲染的完美解决方法
2018/04/25 Javascript
Vue组件的使用及个人理解与介绍
2019/02/09 Javascript
详解TypeScript+Vue 插件 vue-class-component的使用总结
2019/02/18 Javascript
Vue使用lodop实现打印小结
2019/07/06 Javascript
vue实现div可拖动位置也可改变盒子大小的原理
2020/09/16 Javascript
python根据时间生成mongodb的ObjectId的方法
2015/03/13 Python
python实现简单socket程序在两台电脑之间传输消息的方法
2015/03/13 Python
Python实现随机创建电话号码的方法示例
2018/12/07 Python
Django数据库类库MySQLdb使用详解
2019/04/28 Python
Python 迭代,for...in遍历,迭代原理与应用示例
2019/10/12 Python
python正则表达式的懒惰匹配和贪婪匹配说明
2020/07/13 Python
德国的大型美妆个护电商:Flaconi
2020/06/26 全球购物
日期和时间问题
2015/01/04 面试题
土木工程专业自荐信
2013/10/04 职场文书
国际政治个人自荐信范文
2013/11/26 职场文书
质量月口号
2014/06/20 职场文书
入党积极分子批评与自我批评思想汇报
2014/09/14 职场文书
刑事代理授权委托书
2014/09/17 职场文书
公司授权委托书范本
2014/09/18 职场文书
热情服务标语
2014/10/07 职场文书
毕业生评语大全
2015/01/04 职场文书
驳回起诉民事裁定书
2015/05/19 职场文书
2015年教师国培感言
2015/08/01 职场文书
Echarts如何重新渲染实例详解
2022/05/30 Javascript