JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。
JSON的四个基本规则
1.并列的数据之间用逗号(",")分隔
2.映射用冒号(":")表示
3.并列数据的集合(数组)用方括号("[]")表示
4.映射的集合(对象)用大括号("{}")表示
举例:
北京市的面基为16800平方公里,常住人口1600万人。上海市的面基为6400平方公里,常住人口1800万。
转换成JSON格式后:
[ {"城市":"北京","面积":16800,"人口":1600}, {"城市":"上海","面积":6400,"人口":1800} ]
JSON优点:
1.数据格式比较简单,易于读写,格式都是压缩的,占用带宽小。
2.支持多种语言,包括ActionScript,C,C#,ColdFusion,Java,JavaScript,Perl,PHP,Python,Ruby等服务器端语言,便于服务器端的解析。
JSON缺点:
1.要求字符集 必须是Unicode,受约束性强
2.语法过于严谨,必须遵循JSON语法四个原则
JSON的语法可以表示三种类型的值:
1.简单值:使用与JavaScript相同的语法,可以在JSON中表示字符串、数值、布尔值和null,不支持undefined;
JSON表示字符串的方式:“Hello world"(JSON字符串必须使用双引号)
2.对象
对象作为一种复杂数据类型,表示一组无序键值对。每个键值对中的值可以是简单值,也可以是复杂数据类型的值;
与JavaScript的对象字面量相比,JSON对象有两个不一样的地方,首先没声明变量,其次,没有末尾的分号;
JavaScript创建对象字面量:(标准写法中属性不用引号,也可以加上引号)
var object={ name:"Andy", age:29 };
JSON对象:
{ "name":"Andy", "age":29, "school":{ "name":"Hubei Univercity", "location":"Wuchang" } }
3.数组:数组也是一种复杂数据类型,表示一组有序的值的列表,可以通过数组索引来访问其中的值。数组的值也可以是任意类型——简单值、对象或数组。
JavaScript中的数组字面量:
var values=[25,"hi",true];
JSON中把数组和对象结合起来:
{ { "title":"Javascript", "authors":[ "zhangsan" ], edition:3, year:2013 }, { "title":"HTML", "authors":[ "zhangsan", "lisi" ], edition:3, year:2013 },
{
"title":"Css",
"authors":[
"wangwu"
],
edition:1,
year:2011
}
}
JSON数据结构能够被解析为有用的JavaScript对象
把解析JSON数据结构后得到的对象保存到变量books中后,下面一行代码就可取到第三本书的书名
books[2].title
在DOM结构中查找数据的代码:
doc.getElementsByTagName("book")[2].getAttribute("title");
JSON对象有两个方法:stringify()和parse(),在最简单的情况下,这两个方法分别用于把JavaScript对象序列化为JSON字符串和把JSON字符串解析为原生JavaScript值
var book = { "title":"Javascript", "authors":[ "zhangsan" ], edition:3, year:2013 };
var jsonText=JSON.stringify(book);
var bookCopy=JSON.parse(jsonText);
book和bookCopy虽然有相同的属性,但是它们是两个独立的、没有任何关系的对象
序列化选项
JSON.stringify()除了要序列化的JavaScript对象外,还可以接收另外两个参数,这两个参数用于指定以不同的方式序列化JavaScript对象。
第一个参数是过滤器,可以是一个数组,也可以是一个函数;第二个参数是一个选项,表示是否在JSON字符串中保留缩进(默认是没有空格缩进的)。
1.过滤结果
如果过滤器参数是数组,那么JSON.stringify()的结果中将只包含数组中列出的属性
var jsonText=JSON.stringify(book,["title","edition"]);
过滤得到的JSON对象如下:
{"title":"JavaScript","edition":3}
如果过滤器参数是函数:传入的函数接收两个参数,属性(键)名和属性值,根据属性名可以知道怎么处理要序列化的对象中的属性。属性名只能是字符串,而在值并非键值对结构的值事,键名可以是空字符串。(如果函数返回的是undefined,那么相应的属性会被忽略)
var jsonText=JSON.stringify(book,function(key,value){ switch(key){ case "authors": return value.join(",") case "year": return 5000; case "edition": return undefined; default: return value; } });
第一次调用这个函数过滤器,传入的键是一个空字符串,而值就是book对象。序列后的JSON字符串如下:
{"title":"JavaScript","author":"zhangsan","year":5000}
2.字符串缩进
var jsonText=JSON.stringify(book,null,4);//表示缩进为4
最后得到的json对象如下:
{ "title":"Javascript", "authors":[ "zhangsan" ], edition:3, year:2013 }
3.toJSON()方法
var book = { "title":"Javascript", "authors":[ "zhangsan" ], edition:3, year:2013, toJSON:function(){ return this.title; } }; var jsonText=JSON.stringify(book);
最后得到的JSON对象为:"JavaScript"
toJSON()可以作为函数过滤器的补充。假设把一个对象传入JSON.stringify(),序列化该对象的顺序如下:
(1) 如果存在toJSON()方法而且能通过它取得有效的值,则调用该方法。否则,返回对象本身。
(2) 如果提供了第二个参数,应用这个函数过滤器。传入过滤器的值是(1)步返回的值。
(3) 对(2)步返回的每个值进行相应的序列化。
(4) 如果提供了第三个参数,进行相应的格式化。
解析选项
JSON.parse()方法和JSON.stringify()方法用法类似,只是接收的函数被称为还原函数(后者的叫做过滤函数)。在将日期字符串转换为Date()对象时,经常要用到还原函数
1 var book = { 2 "title":"Javascript", 3 "authors":[ 4 "zhangsan" 5 ], 6 edition:3, 7 year:2013, 8 releaseDate:new Date(2011,11,1) 9 }; 10 var jsonText=JSON.stringify(book); 11 var bookCopy=JSON.parse(jsonText,function(key,value){ 12 if(key=="releaseDate"){ 13 return new Date(value); 14 }else{ 15 return value; 16 } 17 }); 18 alert(bookCopy.releaseDate.getFullYear());
在上述代码中,还原函数在遇到"releaseDate"键时,会基于相应的值创建一个新的Date对象,结果就是bookCopy.releaseDate属性中会保存一个Date对象。所以才能基于这个对象调用getFullYear()方法。