什么是JSON
JSON(JavaScript Object Notation),是一种轻量级的基于文本且独立于语言的数据交换格式,比XML更轻巧,它是XML数据交换的一个替代方案。它源于ECMAScript程序语言标准-第3版(ECMA-262 3rd Edition - December 1999)的子集,定义了便于表示结构化数据的一套格式规范,JSON规范是符合ECMAScript语法规范,这样按JSON规范描述出的字符串已是 JavaScript的原生代码串,这使之能通过eval动态的在JSON串与JavaScript对象之间进行转换。如果夸大来说,它是另一种理想的但有别于XML数据交换语言。
JSON建构于两种结构
“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。
这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能
JSON语法规则
对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。
值(value)可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array)。这些结构可以嵌套。
字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。与C或者Java的字符串非常相似。
JSON与XML对比
下面这个例子为JSON
{
employee :
{
firstName: "John",
lastName : "Doe",
employeeNumber : 123,
title : "Accountant"
}
}
这个例子为XML
<employee>
<firstName>John</firstName>
<lastName>Doe</lastName>
<employeeNumber>123</employeeNumber>
<title>Accountant</title>
</employee>
从上面描述看,JSON表示法不正是JavaScript中对象描述的一种方式么?正确,这正是JavaScript中的对象构造的原生代码。既然是原生代码,我们把它转换成JavaScript中的对象,这样我们操作对象就比操作字符串方便多了。
把JSON字符串转换成JavaScript对象:
<script type="text/javascript">
//使用script本身的函数eval将JSON串解析成对象
var e = eval(
'({' +
'employee : ' +
'{' +
'firstName: "John",' +
'lastName : "Doe",' +
'employeeNumber : 123,' +
'title : "Accountant"' +
'}' +
'})'
);
//现在我们可以使用e这个对象了,还可以以点的访问形式来访问对象的属性
alert(e.employee.firstName);
alert(e.employee.lastName);
alert(e.employee.employeeNumber);
alert(e.employee.title);
</script>
XML与JSON对比
经过一番快速浏览后如何?感觉到没有JSON的设计上比XML更轻巧简洁?先前就说过了,正是它符合JavaScript语言对象本身特点,这使得如果服务器传来的文本是符合JavaScript语法定义语句的字符串,那岂不是一条eval方法就能解析了?的确如此~
从上面两者的表示来看,JSON表示法在语法上要比XML要简洁的多,由于不需要使用关闭标签来呼应开始标签,因此许多多余的信息不再出现了,相对XML而言基本上不存在数据冗余,这在传输与响应速度上大在提高了。
另外,JSON不只是在表现形式上有如此的优势,最重要的是可以丢弃以前弄得我们晕头转向的DOM解析了(客户端的JavaScript的XML DOM解析,服务器端的DOM、SAX、Dom4j、Jdom等)。JSON与XML相比对JavaScript有着更好的通用性,一段JSON格式数据经过JavaScript一个简单的方法(eval)即可转换成 JavaScript对象供程序调用,转换方法是浏览器的JavaScript内部定义好的无需再手工编写。而一段XML格式的数据需要调用浏览器内部的 XML解析器工具进行解析后才可以使用。而对于不同内核的浏览器(如IE、Netscape等)XML解析的方法是有差别的,因此需要针对不同浏览器内核做不同的方法封装,从而给客户端开发带来一定的复杂度。相比之下JSON被浏览器解析的速度更快。在服务器端不同的语言也有不同的JSON解析器,可以很方便的解析客户端传过来的字符串,而不像为了读取XML还是借助于这样或那样的API工具。
JSON优缺点
优点:
乍看上去,使用JSON的数据分隔符的优点可能并不那么明显,但存在一个根本性的缘由:它们简化了数据访问。使用这些数据分隔符时, JavaScript引擎对数据结构(如字符串、数组、对象)的内部表示恰好与这些符号相同。
JSON的另一个优点是它的非冗长性。在XML中,打开和关闭标记是必需的,这样才能满足标记的依从性;而在JSON中,所有这些要求只需通过一个简单的括号即可满足。在包含有数以百计字段的数据交换中,传统的XML标记将会延长数据交换时间
此外,JSON受到了擅长不同编程语言的开发人员的青睐。这是因为无论在Haskell中或 Lisp中,还是在更为主流的C#和Java中,开发都可以方便地生成JSON。
缺点:
和许多好东西都具有两面性一样,JSON的非冗长性也不例外,为此JSON丢失了XML具有的一些特性。命名空间允许不同上下文中的相同的信息段彼此混合,然而,显然在JSON中已经找不到了命名空间。JSON与XML的另一个差别是属性的差异,由于JSON采用冒号赋值,这将导致当XML转化为 JSON时,在标识符(XML CDATA)与实际属性值之间很难区分谁应该被当作文本考虑。
另外,JSON片段的创建和验证过程比一般的XML稍显复杂。从这一点来看,XML在开发工具方面领先于JSON。
<html>
<head>
<title> JSON Address Book </title>
</head>
<body>
<div style="text-align:left" id="addressBookResults"></div>
<script type="text/javascript" src="prototype-1.4.0.js"></script>
<script type="text/javascript" src="json.js"></script>
<script type="text/javascript">
//address对象
function address(city,street,zip){
this.city = city;//城市
this.street = street;//街道
this.zip = zip;//邮编
}
//addressbook对象
function addressbook(city,street,zip,name,tel1,tel2){
//addressbook对象中含有address对象属性
this.address = new address(city,street,zip);
//人的名字属性
this.name = name;
//人的电话号码属性,且有两个电话号码
this.phoneNumbers = [tel1,tel2];
}
//创建两个addressbook对象实例,这些信在实际的项目中是由用户通过页面输入的
var addressbookObj1 = new addressbook("Seattle, WA","P.O BOX 54534",
42452,"Ann Michaels",
"561-832-3180","531-133-9098");
var addressbookObj2 = new addressbook("Miami, FL","53 Mullholand Drive",
72452,"Betty Carter",
"541-322-1723","546-338-1100");
//创建要传递给后台的参数对象
var paramObj={};
//因为有多个(这里是两个),我们用数组的形式
paramObj.addressbook=new Array(addressbookObj1,addressbookObj2);
//通过对象实例的toJSONString方法,JavaScript对象转JSON串
var param = paramObj.toJSONString();
//alert(param);
// 定义 service URL
var url = '/json_addressbook/addrbk?timeStamp='+new Date();
// 通过原型创建AJAX请求的WEB服务, 响应后, 回调 showResponse 方式
new Ajax.Request( url, { method: 'post', parameters:"jsonStr="+param,
onComplete: callBack });
// 回调方法,接收服务器返回过来的JSON串,
//并用eval函数或String对象实例parseJSON转换成JavaScript对象
function callBack(originalRequest) {
// 获取服务器返回的JSON原始串
var jsonRaw = originalRequest.responseText;
//原始串转换成JavaScript对象
//var jsonRawObj = eval("(" + jsonRaw + ")");用此种方式也行
var jsonRawObj = jsonRaw.parseJSON();
//从json原始对象中提取HTML格式串
var jsonHtmlStr = jsonRawObj.jsonHtmlStr;
//提取AddreeBook的JSON串
var jsonCode = jsonRawObj.jsonCode;
// 通过eval动态的把JSON响应串构造成JavaScript对象
//var jsonContent = jsonCode.parseJSON();用此种方式也行
jsonContent = eval("(" + jsonCode + ")");
// 从服务器获取的JSON格式串后,显示数据到页面
finalResponse = "<b>服务器返回的JSON串如下: </b><br/><br>";
finalResponse += jsonHtmlStr+"<br/>";
finalResponse += "<br><b>从JSON对象提取信息如下: </b><br/><br>";
// 根据地址薄长度循环.
for (i = 0; i < jsonContent.addressbook.length; i++) {
finalResponse += "<hr/>";
finalResponse += "<i>Name:</i> " + jsonContent.addressbook[i].name + "<br/>";
finalResponse += "<i>Address:</i> " + jsonContent.addressbook[i].address.street
+ " -- " +
jsonContent.addressbook[i].address.city[0] + "," +
jsonContent.addressbook[i].address.zip + ".<br/>";
finalResponse += "<i>Telephone numbers:</i> "
+ jsonContent.addressbook[i].phoneNumbers[0] + " & " +
jsonContent.addressbook[i].phoneNumbers[1] + ".";
}
// 把结果置换到结果区域并显示
document.getElementById("addressBookResults").innerHTML = finalResponse;
}
</script>
</body>
</html>
服务器返回的JSON串如下:
{"addressbook": [
{
"address": {
"city": [
"Seattle, WA",
"changsha"
],
"street": ["P.O BOX 54534"],
"zip": [42452]
},
"name": "Ann Michaels",
"phoneNumbers": [
"561-832-3180",
"531-133-9098"
]
},
{
"address": {
"city": [
"Miami, FL",
"changsha"
],
"street": ["53 Mullholand Drive"],
"zip": [72452]
},
"name": "Betty Carter",
"phoneNumbers": [
"541-322-1723",
"546-338-1100"
]
}
]}
从JSON对象提取信息如下:
Name: Ann Michaels
Address: P.O BOX 54534 -- Seattle, WA,42452.
Telephone numbers: 561-832-3180 & 531-133-9098.
Name: Betty Carter
Address: 53 Mullholand Drive -- Miami, FL,72452.
Telephone numbers: 541-322-1723 & 546-338-1100.