我们在使用JSON数据时遇到最多的操作是对JSON格式的数据进行序列化和反序列化操作,在这里我想介绍下什么是JSON数据,JS原生的JSON对象提供的支持及浏览器兼容的问题。
1、什么是JSON
在http://json.org/中是这样介绍JSON:
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript(ECMA-262标准第三版)的一个子集。采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。
JSON采用key/value的形式来表示数据,其中使用“{}”表示对象,而“[]”则表示数组,详细的语法可以参考json.org。
JSON对象:{"name":"LiLei","age":19,"sex":"male"} JSON数组:[ {"name":"LiLei","age":19,"sex":"male"}, {"name":"HanMei","age":18,"sex":"famale"} ]
就web开发来讲,JSON数据有三个好处:
简洁,方便前台数据操作 - 与XML相比,JSON的分隔符仅限于引号、冒号、逗号、大括号和中括号,并且没有闭合标签的要求,这使得JSON结构更加的简洁。
体积小,传输快。
易用性 - 由于JSON的语法本身就是JavaScript的一个子集,因此对于一个JSON结构几乎不需要额外的解析和查找,可以像使用原生JavaScript对象那样去使用JSON,而XML则需要通过DOM解析来访问。
因此,JSON在当前的Web开发用中使用的越来越广泛。其中最常用的两个操作是序列化和反序列化。目前,很多JavaScript库提供都提供了对着两个操作的支持,不过随着ECMA起草了JSON序列化和反序列化的相关标准后,各大浏览器也相应的增加了对JSON的原生支持。
2、原生JSON对象
目前支持原生JSON对象的浏览器包括:IE8、Firefox3.5以及Chrome3.0/4.0。原生的JSON对象是一个只包括parse方法与stringify方法的纯粹的对象,用于解析和构建JSON文本。
2.1、 JSON.parse(text [ , reviver ] )
parse方法的作用是进行反序列化,即将一个符合JSON语法的字符串解析成一个JavaScript对象。该方法可以接受两个参数text与reviver,其中reviver是可选的。text是需要反序列化的字符串,reviver则是一个可选的函数,在反序列化的过程中,每当解析到对象的一个属性时都会将key和value作为参数传递给reviver并执行,之后将返回的结果作为当前key对应值(如果解析的是数组则传递的是当前元素的索引以及元素本身)。如果返回的是undefined则会在解析后的对象中删除对应的属性。具体的使用参见下面的代码:
//简单对象 var str = '{"name":"LiLei","age":19,"sex":"male"}'; var obj = JSON.parse(str); alert(obj.name); //LiLei var obj2 = JSON.parse(str,function(k,v){ if(k == "name"){ return "HanMeiMei"; } return v; }); alert(obj2.name); //HanMeiMei //数组 var str = '[{"name":"LiLei","age":19,"sex":"male"},'+ '{"name":"Lucy","age":17,"sex":"female"}]'; var obj = JSON.parse(str); alert(obj[0].name);// LiLei alert(obj[1].name);//Lucy var obj2 = JSON.parse(str,function(k,v){ if(k == "name"){ return "HanMeiMei"; } return v; }); alert(obj2[0].name); //HanMeiMei alert(obj2[1].name); //HanMeiMei //复杂对象 var str = '{"class":"javascript",'+ '"teacher":{"name":"HanMeiMei","age":28,"sex":"female"},'+ '"students":[{"name":"LiLei","age":19,"sex":"male"},'+ '{"name":"Lucy","age":17,"sex":"female"}]}'; var obj = JSON.parse(str); alert(obj.teacher.name); // HanMeiMei alert(obj.students[0].name); //LiLei var obj2 = JSON.parse(str,function(k,v){ if(k == "teacher"){ v.name = "Poly"; } return v; }); alert(obj2.teacher.name); // Poly alert(obj2.students[0].name); // LiLei alert(obj2.students[1].name); // Lucy
注意:使用JSON.parse的时候,对象的每个属性都必须用双引号括起来,否则会抛出异常;
var str = '{company:"kedacom"}'; var json = JSON.parse(str); //解析出现异常 var str2 = "{'company':'kedacom'}"; var json2 = JSON.parse(str2); //解析出现异常
2.2、JSON.stringify(value [ , replacer [ , space ] ] )
stringify方法的作用是进行序列化,即将一个JavaScript对象序列化成JSON结构的字符串。该方法最多可以包含3个参数:
value - 需要序列化的JavaScript对象。
replacer - 可选,可以是函数或者数组,
如果是函数,则用于过滤序列化的结果。在序列化的执行过程中,每当遍历到对象的一个属性时,都会将属性的key和value传递给replacer并执行,并将执行结果作为该属性的值。
如果是一个数组,则必须保证数组中的每个元素都是字符串,该数组参数用于指定value中需要进行序列化的属性,如果是对数组进行序列化则会忽略数组形式的replacer参数。
在使用函数作为replacer时需要注意的是,由于replacer返回的内容仍然会执行序列化,因此如果是返回对象则层次不要太深,不然很容易出“堆栈溢出”的异常,此外如果返回的是undefined则属性会被直接删除掉,而不会出现在字符串中。
space - 可选,可以是数字或字符串。用于格式化输出,使输出的JSON字符串更易于阅读,这在需要人工检查时非常的有用。如果是数字则表示每一级缩进的空格数,如果是字符串则表示每一级缩进都使用该字符串。使用示例:
1)只有一个参数的情况下:
var student = {"name":"LiLei","age":30,"location":"China"}; var json = JSON.stringify(student); document.write(student); // [object Object] document.write(json); // {"name":"LiLei","age":"30","location":"China"}
2)第二个参数存在,并且是函数
var student = {"name":"LiLei","age":30,"location":"China"}; var json = JSON.stringify(student,function(k,v){ if(k == "name"){ return "poly"; } return v; }); document.write(json); //{"name":"poly","age":30,"location":"China"} var students = ["LiLei","poly","hanmeimei"]; var json = JSON.stringify(students, function (key,value) { return value.toString().toUpperCase(); }); document.write(json);// "LILEI,POLY,HANMEIMEI"
3)第二个参数存在,并且是数组
// value是对象,并且replacer为数组时,返回只包含有replacer指定属性的对象 var student = {"name":"LiLei","age":30,"location":"China"}; var json = JSON.stringify(student,["name","location"]); document.write(json); //{"name":"LiLei","location":"China"} // value是数组,并且replacer为数组时,replace参数被忽略 var students = ["LiLei","poly","hanmeimei"]; var json = JSON.stringify(students); var json2 = JSON.stringify(students, ["0","2"]); document.write(json); // ["LiLei","poly","hanmeimei"] document.write(json2); //["LiLei","poly","hanmeimei"]
4)第三个参数存在,并且是数字,表示缩进几个字符,此时最大值为10
var student = {"name":"LiLei","age":30,"location":"China"}; var json = JSON.stringify(student,["name","location"]); alert(json); var student = {"name":"LiLei","age":30,"location":"China"}; var json = JSON.stringify(student,["name","location"],4); alert(json);
5)第三个参数存在,并且是转义字符
var student = {"name":"LiLei","age":30,"location":"China"}; var json = JSON.stringify(student,["name","location"]); alert(json); var student = {"name":"LiLei","age":30,"location":"China"}; var json = JSON.stringify(student,["name","location"],"\t"); alert(json);
6) 第三个参数存在,并且仅仅是字符串,就在每行输出值的时候把这些字符串附加上去就OK。最大长度也是10个字符
var student = {"name":"LiLei","age":30,"location":"China"}; var json = JSON.stringify(student,["name","location"]); alert(json); var student = {"name":"LiLei","age":30,"location":"China"}; var json = JSON.stringify(student,["name","location"],"kedacom"); alert(json);
3、原生JSON的的浏览器兼容
目前支持原生JSON对象的浏览器包括:IE8(S)、Firefox3.5以及Chrome3.0/4.0,对于更低版本的浏览器支持在网络上又很多的解决方案,目前使用最为广泛和成熟的解决方案是在项目中引入json.js库,该扩展库是由大师Douglas Crockford扩展实现(有兴趣的童靴可以读下源码),在最近的一次更新中可以看到如下建议,json.js文件应该使用被最新的json2.js替换。
/* json.js 2013-05-26 Public Domain No warranty expressed or implied. Use at your own risk. This file has been superceded by http://www.JSON.org/json2.js See http://www.JSON.org/js.html */
在https://github.com/douglascrockford/JSON-js可以下载到json.js和json2.js两个文件。
下面就通过在IE6中引入json2.js进行一个简单测试:
//没有引入json2.js库的版本 <!DOCTYPE HTML> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <script> if(JSON){ var student = {"name":"LiLei","age":30,"location":"China"}; var s = JSON.stringify(student,["name","location"]); alert(s); }else{ alert("不支持JSON对象"); } </script> </head><body></body></html>
执行报错:
引入json2.js,代码如下:
…… <script src="json2.js" type="text/javascript"></script> ……
执行结果:
4、小结
认识javascript也不短的时间了,一直不知道原生JSON对象的存在,知道最近想着从头整理下自己的javascript知识,才知道它的存在,惭愧啊惭愧啊。于是乎,在网上找了些资料,并结合一些例子,希望能给童靴们一些帮助。
5、参考
http://technet.microsoft.com/zh-cn/sysinternals/cc836459(v=vs.94)