深入理解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 相关文章推荐
用js生产批量批处理执行命令
Jul 28 Javascript
javascript自执行函数之伪命名空间封装法
Dec 25 Javascript
jQuery实现可以控制图片旋转角度效果(附demo源码下载)
Jan 27 Javascript
javascript实现数组去重的多种方法
Mar 14 Javascript
bootstrap flask登录页面编写实例
Nov 01 Javascript
JavaScript数据结构之二叉树的计数算法示例
Apr 13 Javascript
jQuery 实现图片的依次加载图片功能
Jul 06 jQuery
vue+webpack实现异步加载三种用法示例详解
Apr 24 Javascript
微信小程序实现自定义modal弹窗封装的方法
Jun 15 Javascript
vue实现多个元素或多个组件之间动画效果
Sep 25 Javascript
JS 实现获取验证码 倒计时功能
Oct 29 Javascript
element-ui table span-method(行合并)的实现代码
Dec 20 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
DOTA2【瓜皮时刻】Vol.91 RTZ山史最惨“矿难”
2021/03/05 DOTA
php递归使用示例(php递归函数)
2014/02/14 PHP
Eclipse的PHP插件PHPEclipse安装和使用
2014/07/20 PHP
php设计模式之建造器模式分析【星际争霸游戏案例】
2020/01/23 PHP
Jquery + Ajax调用webService实例代码(asp.net)
2010/08/27 Javascript
JavaScript Math.ceil() 函数使用介绍
2013/12/11 Javascript
教你在heroku云平台上部署Node.js应用
2014/07/30 Javascript
jQuery实现仿腾讯迷你首页选项卡效果代码
2015/09/17 Javascript
基于JavaScript代码实现随机漂浮图片广告
2016/01/05 Javascript
AngularJS实现ajax请求的方法
2016/11/22 Javascript
利用vue组件自定义v-model实现一个Tab组件方法示例
2017/12/06 Javascript
Angular中点击li标签实现更改颜色的核心代码
2017/12/08 Javascript
详解使用create-react-app添加css modules、sasss和antd
2018/07/31 Javascript
vue.js仿hover效果的实现方法示例
2019/01/28 Javascript
VSCode使用之Vue工程配置eslint
2019/04/30 Javascript
Vue使用vue-recoure + http-proxy-middleware + vuex配合promise实现基本的跨域请求封装
2019/10/21 Javascript
基于Angular 8和Bootstrap 4实现动态主题切换的示例代码
2020/02/11 Javascript
一个基于flask的web应用诞生 组织结构调整(7)
2017/04/11 Python
分享一下如何编写高效且优雅的 Python 代码
2017/09/07 Python
Python 数据库操作 SQLAlchemy的示例代码
2019/02/18 Python
Pytorch实现GoogLeNet的方法
2019/08/18 Python
Python 用三行代码提取PDF表格数据
2019/10/13 Python
pytorch模型预测结果与ndarray互转方式
2020/01/15 Python
使用 Python 处理3万多条数据只要几秒钟
2020/01/19 Python
Python猴子补丁Monkey Patch用法实例解析
2020/03/23 Python
html5 利用重力感应实现摇一摇换颜色可用来做抽奖等等
2014/05/07 HTML / CSS
HTML5 Canvas实现360度全景图的示例代码
2018/01/29 HTML / CSS
YesBabyOnline美国:全球性的在线婚纱礼服工厂
2018/05/05 全球购物
什么情况下你必须要把一个类定义为abstract的
2013/01/06 面试题
太太口服液广告词
2014/03/20 职场文书
党的群众路线教育实践活动心得体会(乡镇)
2014/11/03 职场文书
教师党员群众路线教育实践活动心得体会
2014/11/04 职场文书
对外汉语教师推荐信
2015/03/27 职场文书
python状态机transitions库详解
2021/06/02 Python
使用Ajax实现无刷新上传文件
2022/04/12 Javascript
vue项目配置sass及引入外部scss文件
2022/04/14 Vue.js