深入理解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 篱式条件判断
Aug 22 Javascript
Js sort排序使用方法
Oct 17 Javascript
javascript作用域、作用域链(菜鸟必看)
Jun 16 Javascript
angular实现form验证实例代码
Jan 17 Javascript
详解前端构建工具gulpjs的使用介绍及技巧
Jan 19 Javascript
Angular2 自定义validators的实现方法
Jul 05 Javascript
Mui使用jquery并且使用点击跳转新窗口的实例
Aug 19 jQuery
在 vue-cli v3.0 中使用 SCSS/SASS的方法
Jun 14 Javascript
在element-ui的el-tree组件中用render函数生成el-button的实例代码
Nov 05 Javascript
简单了解JavaScript中常见的反模式
Jun 21 Javascript
vue router总结 $router和$route及router与 router与route区别
Jul 05 Javascript
prettier自动格式化去换行的实现代码
Aug 25 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
全国FM电台频率大全 - 6 辽宁省
2020/03/11 无线电
php生成略缩图代码
2012/07/16 PHP
PHP中判断变量为空的几种方法小结
2013/11/12 PHP
Codeigniter实现智能裁剪图片的方法
2014/06/12 PHP
PHP中strlen()和mb_strlen()的区别浅析
2014/06/19 PHP
百度地图经纬度转换到腾讯地图/Google 对应的经纬度
2015/08/28 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
php插件Xajax使用方法详解
2017/08/31 PHP
JAVASCRIPT实现的WEB页面跳转以及页面间传值方法
2010/05/13 Javascript
js字符串截取函数substr substring slice使用对比
2013/11/27 Javascript
JavaScript获取各大浏览器信息图示
2015/11/20 Javascript
javascript拖拽应用实例
2016/03/25 Javascript
走进javascript——不起眼的基础,值和分号
2017/02/24 Javascript
自定义vue全局组件use使用、vuex的使用详解
2017/06/14 Javascript
javascript中new Array()和var arr=[]用法区别
2017/12/01 Javascript
js实现前面自动补全位数的方法
2018/10/10 Javascript
微信小程序时间选择插件使用详解
2018/12/28 Javascript
详解node.js 事件循环
2020/07/22 Javascript
解决vue使用vant下拉框van-dropdown-item 绑定title值不变问题
2020/08/05 Javascript
小程序实现列表倒计时功能
2021/01/29 Javascript
[07:40]DOTA2每周TOP10 精彩击杀集锦vol.4
2014/06/25 DOTA
将tensorflow的ckpt模型存储为npy的实例
2018/07/09 Python
Sanic框架Cookies操作示例
2018/07/17 Python
django 将model转换为字典的方法示例
2018/10/16 Python
python使用装饰器作日志处理的方法
2019/07/11 Python
Python TCP通信客户端服务端代码实例
2019/11/21 Python
Django基于客户端下载文件实现方法
2020/04/21 Python
英国标志性生活方式品牌:Skinnydip London
2019/12/15 全球购物
小学语文教学反思
2014/02/10 职场文书
保护环境建议书100字
2014/05/13 职场文书
初中生300字旷课检讨书
2014/11/19 职场文书
2015年教师节贺卡寄语
2015/03/24 职场文书
客服专员岗位职责范本
2015/04/07 职场文书
《酸的和甜的》教学反思
2016/02/18 职场文书
2016年六一文艺汇演开幕词
2016/03/04 职场文书
springmvc直接不经过controller访问WEB-INF中的页面问题
2022/02/24 Java/Android