深入理解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使用正则控制input输入框允许输入的值方法大全
Jun 19 Javascript
JavaScript数组迭代器实例分析
Jun 09 Javascript
js实现下拉列表选中某个值的方法(3种方法)
Dec 17 Javascript
浅谈Angular2 ng-content 指令在组件中嵌入内容
Aug 18 Javascript
详解webpack babel的配置
Jan 09 Javascript
React native ListView 增加顶部下拉刷新和底下点击刷新示例
Apr 27 Javascript
20个最常见的jQuery面试问题及答案
May 23 jQuery
在小程序中集成redux/immutable/thunk第三方库的方法
Aug 12 Javascript
Angular如何由模板生成DOM树的方法
Dec 23 Javascript
在博客园博文中添加自定义右键菜单的方法详解
Feb 05 Javascript
深入解析微信小程序开发中遇到的几个小问题
Jul 11 Javascript
react中的DOM操作实现
Jun 30 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实现蛇形矩阵,回环矩阵及数字螺旋矩阵的方法分析
2017/05/29 PHP
laravel框架关于搜索功能的实现
2018/03/15 PHP
php变量与字符串的增删改查操作示例
2020/05/07 PHP
如何在PHP中使用数组
2020/06/09 PHP
javascript smipleChart 简单图标类
2011/01/12 Javascript
分享一个用Mootools写的鼠标滑过进度条改变进度值的实现代码
2011/12/12 Javascript
给文字加上着重号的JS代码
2013/11/12 Javascript
jquery日历控件实现方法分享
2014/03/07 Javascript
移动端点击图片放大特效PhotoSwipe.js插件实现
2016/08/25 Javascript
JS实现动态增加和删除li标签行的实例代码
2016/10/16 Javascript
jQuery实现选中行变色效果(实例讲解)
2017/07/06 jQuery
JavaScript贪吃蛇小组件实例代码
2017/08/20 Javascript
Extjs 中的 Treepanel 实现菜单级联选中效果及实例代码
2017/08/22 Javascript
jQuery中的类名选择器(.class)用法简单示例
2018/05/14 jQuery
jQuery表单选择器用法详解
2019/08/22 jQuery
vue keep-alive 动态删除组件缓存的例子
2019/11/04 Javascript
vue 中使用print.js导出pdf操作
2020/11/13 Javascript
[01:00:25]NB vs Secret 2018国际邀请赛小组赛BO1 B组加赛 8.19
2018/08/21 DOTA
python实现图像识别功能
2018/01/29 Python
遗传算法python版
2018/03/19 Python
Python实现快速傅里叶变换的方法(FFT)
2018/07/21 Python
Python多进程编程multiprocessing代码实例
2020/03/12 Python
python DES加密与解密及hex输出和bs64格式输出的实现代码
2020/04/13 Python
Python configparser模块常用方法解析
2020/05/22 Python
Python数据可视化图实现过程详解
2020/06/12 Python
pycharm中如何自定义设置通过“ctrl+滚轮”进行放大和缩小实现方法
2020/09/16 Python
LocalStorage记住用户和密码功能
2017/07/24 HTML / CSS
捷克鲜花配送:Florea.cz
2018/10/29 全球购物
电子商务应届生求职信
2013/11/16 职场文书
网站开发实习生的自我评价
2013/12/11 职场文书
求职自荐信怎么写
2014/03/06 职场文书
房屋分割离婚协议书范本
2014/12/01 职场文书
幼儿园教师教学反思
2016/03/02 职场文书
2019年聘任书的写作格式及范文!
2019/07/03 职场文书
python实现网络五子棋
2021/04/11 Python
pytorch 中autograd.grad()函数的用法说明
2021/05/12 Python