深入理解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 相关文章推荐
JQuery 引发两次$(document.ready)事件
Jan 15 Javascript
jquery实现图片上传之前预览的方法
Jul 11 Javascript
js弹出窗口返回值的简单实例
May 28 Javascript
详解获取jq ul第一个li定位的四种解决方案
Nov 23 Javascript
input获取焦点时底部菜单被顶上来问题的解决办法
Jan 24 Javascript
基于JavaScript实现下拉列表左右移动代码
Feb 07 Javascript
详解Web使用webpack构建前端项目
Sep 23 Javascript
vue router自动判断左右翻页转场动画效果
Oct 10 Javascript
微信小程序学习笔记之登录API与获取用户信息操作图文详解
Mar 29 Javascript
JS多个表单数据提交下的serialize()应用实例分析
Aug 27 Javascript
JS回调函数深入理解
Oct 16 Javascript
JavaScript使用prototype属性实现继承操作示例
May 22 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
ThinkPHP的L方法使用简介
2014/06/18 PHP
PHP临时文件的安全性分析
2014/07/04 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
PHP实现微信支付(jsapi支付)流程步骤详解
2018/03/15 PHP
List Installed Hot Fixes
2007/06/12 Javascript
防止动态加载JavaScript引起的内存泄漏问题
2009/10/08 Javascript
13 个JavaScript 性能提升技巧分享
2012/07/26 Javascript
Js制作简单弹出层DIV在页面居中 中间显示遮罩的具体方法
2013/08/08 Javascript
父元素与子iframe相互获取变量和元素对象的具体实现
2013/10/15 Javascript
表单元素与非表单元素刷新区别详细解析
2013/11/06 Javascript
Mac OS X 系统下安装和部署Egret引擎开发环境
2014/09/03 Javascript
JS实现仿腾讯微博无刷新删除微博效果代码
2015/10/16 Javascript
JS中Select下拉列表类(支持输入模糊查询)功能
2017/01/17 Javascript
JSONP基础知识详解
2017/03/19 Javascript
使用JQ完成表格隔行换色的简单实例
2017/08/25 Javascript
通过 JS 判断页面是否有滚动条的实现方法
2018/04/05 Javascript
react native 文字轮播的实现示例
2018/07/27 Javascript
JavaScript常见JSON操作实例分析
2018/08/08 Javascript
JS实现的A*寻路算法详解
2018/12/14 Javascript
Vue.js原理分析之nextTick实现详解
2020/09/07 Javascript
el-table表头根据内容自适应完美解决表头错位和固定列错位
2021/01/07 Javascript
[52:03]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第三场 1月31日
2021/03/11 DOTA
python实现的系统实用log类实例
2015/06/30 Python
OpenCV-Python实现轮廓检测实例分析
2018/01/05 Python
如何用Python破解wifi密码过程详解
2019/07/12 Python
django之使用celery-把耗时程序放到celery里面执行的方法
2019/07/12 Python
python yield和Generator函数用法详解
2020/02/10 Python
Django模型验证器介绍与源码分析
2020/09/08 Python
Python导入父文件夹中模块并读取当前文件夹内的资源
2020/11/19 Python
python 使用OpenCV进行简单的人像分割与合成
2021/02/02 Python
用CSS3实现无限循环的无缝滚动的实例代码
2017/07/04 HTML / CSS
"序列点" 是什么
2016/07/29 面试题
餐饮业会计岗位职责
2013/12/19 职场文书
管理心得体会
2013/12/28 职场文书
2014年接待工作总结
2014/11/26 职场文书
Golang表示枚举类型的详细讲解
2021/09/04 Golang