一篇文章读懂JSON
什么是json?
W3C JSON定义修改版:
- JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
- JSON 是轻量级的文本数据交换格式,并不是编程语言
- JSON 独立于语言存在
- JSON 具有自我描述性,更易理解
读书,有必要对概念有较为清晰的认识。以下就涉及到的名词解释一下。
1)JavaScript对象表示法。JSON语法无非是对JavaScript对象的表述,甭管是用对象数组、单纯的对象还是组成对象的简单值,这些都只是为了描述对象或者多个对象服务的。如果不理解,那么请看以下例子。
10000 // 简单值,传递的数据几乎看不懂,到底代表什么意思?10000人?10000元? ["Sally", 25, 10000] // 数组,传递的数据可能无法解读,Sally也许是一个品牌,25或许是品牌创立时间长度 {"name": "Sally", "age": 25, "salary": 10000} // 一个对象,能够读懂数据意义 [{"name": "Sally", "age": 25, "salary": 10000}, {"name": "Jimmy", "age": 30, "salary": 20000}] // 对象数组(多个对象),能够读懂数据意义
Array和Object在JavaScript中都是复杂数据类型,但是如果需要产生意义的数据,以键对值(name/value)形式才是最佳途径。虽然数组等单独存在的形式虽然仍然可以作为数据传输,但是显然没有对象形式来的一目了然。
当然,我个人感觉通过名字来取值比使用数组索引取值要来的直观、方便、可靠。而且,这种方式和XML也很相似。
2)JSON属于轻量级的数据交换协议。一般而言,轻量级(lightweight)等价于耦合度低、侵入性小。不过在这里既可以指JSON与编程语言的耦合度小,又可以说明JSON文档储存相同信息所占的资源少的。再者,JSON和XML一样,既可以作为配置文件、也可以作为数据传输协议存在,当然,在JS中使用JSON比XML更优。
3)JSON语法上属于ECMAScript定义的子集,但是并不代表JSON从属于JavaScript。必须要明确一点,JSON是种数据传输的格式,不是一门编程语言,也不是只有JavaScript才使用JSON,比如近些年比较热门的Python、Java也能够使用JSON,即只要有相应的库(满足JSON协议)即可使用JSON。
本节最后用ECMAScript-404规范中的一段话概括上面的内容。
JSON是一种轻量级、基于文本、独立于语言的数据交换格式。JSON源于ECMAScript编程语言,但是相对编程语言独立。JSON为可移植的结构化数据表示定义了一个结构化规则集。
JSON的诞生
在JSON协议诞生之前,XML作为在互联网上传输数据的事实标准存在已经很多年。但是,业界也有对XML的抱怨,比如XML文档虽然易读写,但是相对来讲比较繁锁、冗长,虽然能够几乎横跨所有编程语言而且传输数据量大,但是执行效率过低等等。
大概在2001年左右,JSON便开始了小规模应用。直到2006年,一个叫Douglas Crockford的人,将JSON作为RFC文档提交到IETF,之后JSON正式成为了计算机网络通讯的标准协议之一。
可能没有学习过计算机网络的人会感到疑惑,开始不是说数据格式吗?怎么这里又变成协议了?两者到底是什么关系?
用比较有深度的话来说,协议就是涵盖了语义、语法、同步三大问题。而格式可能只能包含语义、语法。 也就是说在概念上,协议>=格式。
json语法
JSON语法支持的数据结构:
1)简单值
json支持javascript的简单数据类型String
(字符串)、Number
(数值)、Boolean
(布尔值),以及特殊数据类型null
。但是不支持ECMAScript中的undefined
。
注意:JSON字符串必须使用双引号(单引号会导致语法错误,与JS有区别),key必须使用双引号。如下的前四种形式都是错误的。
{'name': "Sally"} // 错 {name: "Sally"} // 错 {"name": 'Sally'} // 错 {"name": Sally} // 错
{"name": "Sally"} // 对
{"age": 25} // 对
2)对象
JavaScript中对象字面量,可以给属性加单引号对('')、双引号对(""),甚至可以不加引号。如下图所示,不加双引号和加双引号均可。
但是,我们在开发JavaScript程序时,往往会补上双引号对("")。
var object = { "name": "Nicholas", "age": 29 };
与JavaScript中使用JSON形式创建对象不同,真正的JSON协议是没有变量声明以及变量名的(JSON作为数据传输协议,没有变量概念)。其次,JSON也没有语句末尾的分号";"(JSON不是JS语句,不需要分号)
3)数组
读到这里,可能你还会存在如下问题:
为什么JSON不支持ECMAScript语法中的特殊值undefined关键词?
为什么JSON对象属性必须使用双引号?
为什么JSON语句行末尾不需要加分号?
为什么JSON中没有变量的概念?
以上问题的解答就是基于一点,那就是JSON是一种用于各种编程语言之间数据交换的格式标准。
并不是每一种编程语言都支持undefined(比如Java、python等都没有undefined关键词),但是其余的数据类型在别的编程语言中都能得到原生支持;
对象属性必须加引号可以避免在属性值中出现空格导致信息出错问题,还方便接收方判断属性范围;
分号、变量对JSON来说毫无意义,因为JSON得目的是传输不可变的数据,只要拥有足够多对数据区分的符号足以。
解析与序列化
ECMAScript 5对解析JSON的行为进行规范,定义了全局对象JSON,即浏览器原生JSON对象。
JSON对象定义了两个方法:
- stringify() ,JS对象序列化为JSON字符串
- parse() ,JSON字符串解析为JS对象
为什么JavaScript不推荐使用其原生函数eval()解析json?
eval函数功能强大,常用于求值。但是,eval函数并不会对求值内容做检查,尤其是对字符串。因此,使用eval得到的并不是JSON,可能是一段恶意程序。
json和xml比较
Douglas Crockford认为,与xml相比,JSON在JavaScript中读写结构化数据的更优选择。因为在JavaScript中可以直接用原生的eval()函数解析JSON数据,而不必再创建DOM对象。
参考文献
1、《Professional JavaScript for Web Developers 3rd Edtion》 Nicholas C.Zakas
4、Standard ECMA-404文档