深入理解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 相关文章推荐
prototype class详解
Sep 07 Javascript
StringTemplate遇见jQuery冲突的解决方法
Sep 22 Javascript
判断输入是否为空,获得输入类型的JS代码
Oct 30 Javascript
JSON相关知识汇总
Jul 03 Javascript
javascript每日必学之运算符
Feb 16 Javascript
AngularJS 最常用的功能汇总
Feb 17 Javascript
jquery easyui dataGrid动态改变排序字段名的方法
Mar 02 Javascript
微信小程序 五星评价功能的实现
Mar 09 Javascript
一个Vue视频媒体多段裁剪组件的实现示例
Aug 09 Javascript
vue中使用input[type=&quot;file&quot;]实现文件上传功能
Sep 10 Javascript
React通过redux-persist持久化数据存储的方法示例
Feb 14 Javascript
vue组件vue-esign实现电子签名
Apr 21 Vue.js
深入理解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
apache+mysql+php+ssl服务器之完全安装攻略
2006/09/05 PHP
php访问查询mysql数据的三种方法
2006/10/09 PHP
PHP 多进程 解决难题
2009/06/22 PHP
PHP中使用Session配合Javascript实现文件上传进度条功能
2014/10/15 PHP
Laravel实现用户注册和登录
2015/01/23 PHP
PHP mysql事务问题实例分析
2016/01/18 PHP
javascript中的几个运算符
2007/06/29 Javascript
JQuery FlexiGrid的asp.net完美解决方案 dotNetFlexGrid-.Net原生的异步表格控件
2010/09/12 Javascript
JQuery操作表格(隔行着色,高亮显示,筛选数据)
2012/02/23 Javascript
javascript 基础篇2 数据类型,语句,函数
2012/03/14 Javascript
jQuery+CSS3实现点赞功能
2017/03/13 Javascript
AngularJS读取JSON及XML文件的方法示例
2017/05/25 Javascript
Kindeditor单独调用单图上传增加预览功能的实例
2017/07/31 Javascript
微信小程序实现animation动画
2018/01/26 Javascript
玩转vue的slot内容分发
2018/09/22 Javascript
Vue源码中要const _toStr = Object.prototype.toString的原因分析
2018/12/09 Javascript
element-ui表格合并span-method的实现方法
2019/05/21 Javascript
layui自己添加图片按钮并点击跳转页面的例子
2019/09/14 Javascript
基于JS实现父组件的请求服务过程解析
2019/10/14 Javascript
原生js拖拽实现图形伸缩效果
2020/02/10 Javascript
JQuery插件tablesorter表格排序实现过程解析
2020/05/28 jQuery
基于vue实现简易打地鼠游戏
2020/08/21 Javascript
python线程锁(thread)学习示例
2013/12/04 Python
Python实现多线程下载文件的代码实例
2014/06/01 Python
Python 20行简单实现有道在线翻译的详解
2019/05/15 Python
Python分布式进程中你会遇到的问题解析
2019/05/28 Python
python实现列表中最大最小值输出的示例
2019/07/09 Python
python实现的接收邮件功能示例【基于网易POP3服务器】
2019/09/11 Python
CSS3教程(5):网页背景图片
2009/04/02 HTML / CSS
Dogeared官网:在美国手工制作的珠宝
2019/08/24 全球购物
房屋出售协议书
2014/04/10 职场文书
《长相思》听课反思
2014/04/10 职场文书
七一党日活动总结
2014/07/08 职场文书
职工宿舍管理制度
2015/08/05 职场文书
php+laravel 扫码二维码签到功能
2021/05/15 PHP
win11电脑关机鼠标灯还亮怎么解决? win11关机后鼠标灯还亮解决方法
2023/01/09 数码科技