JSON


JSON就是一种数据格式,和XML一样,都是一种结构化类型的数据表示方式。很多编程语言都可以对JSON格式的数据进行解析和序列化。

一 JSON语法

JSON 格式支持三种语法值:简单值,数组,对象

JSON格式的数据,其实就是一段字符串。

简单值:

直接是数值型数据,字符串,null,布尔值,但是不知此JS中独有的undefined类型的值。下面的代码直接进行加载,看是否报错

 

<span style="font-size:18px;">	100
	true;
	//abc;//报错了,当成了变量来处理
	"acd";//正确,用双引号括起来了,当做是JSON格式的数据
	null;
	undefined;		//不支持</span>


数组:

 

JSON格式的数组表示方法,相比普通的数组字面量方式,少了赋值符号和分号

 

<span style="font-size:18px;">JavaScript 数组字面量表示法:
var box = [100, 'Lee', true];
而 JSON 中的数组表示法同样没有变量赋值和分号:
[100, "Lee", true]</span>


对象:

JSON格式的数据中,对象的表示方法相对与JS中对象的字面量的区别是:没有赋值符号,键值对中将键和值都用引号括起来,最好是双引号。如果在JS文件中要不报错,就必须写在一行上面,并且用引号括起来。若写在单独的JSON文件中则不需要

 

<span style="font-size:18px;">	//JS 中对象的字面量表示方法这种带有赋值符号的对象,不是JSON格式的数据
	var box = {
			name:"abc",
			age:22
		}

	//JSON 格式中的对象形式如下,键值对都是用引号括起来的,最好是双引号,但是下面这个同样会报错
	{
		"name":"acd",	
		"age":23	
	}

	//JSON 格式的对象表示形式,JSON格式是一个字符串,故要用引号括起来
	'{"name" : "abc","age" : 23,"height" : 134}'</span>

 


最常用语法:

最常用的一种JSON数据格式是数组+对象,一个数组中存放N个元素,每一个元素又是一个对象

 

<span style="font-size:18px;">//最常用的JSON格式的表示方法,是数组对象表示法:而且这种写法还不会报错
	[
		{
			"title":"one",
			"age":23,
			"height":178
		},
		{
			"title":"two",
			"age":23,
			"height":177
		},
		{
			"title":"three",
			"age":24,
			"height":176
		}
	]</span>

 


二 解析JSON数据

一般情况下,我们可以把 JSON 结构数据保存到一个文本文件里,然后通过XMLHttpRequest 对象去加载它,得到这串结构数据字符串。模拟加载 JSON 文本文件的数据,并且赋值给变量:

 

<span style="font-size:18px;">var box = '[{"name" : "a","age" : 1},{"name" : "b","age" : 2}]';</span>

这短代码模拟了 var box = load('demo.json');赋值过程。 因为通过 load 加载的文本文件,不管内容是什么,都必须是字符串。所以两边要加上双引号。当加载了JSON格式的数据后,需要对其解析成原声的JS代码才能够使用它。

 

eval()方法解析:

通过eval()方法可以执行一段字符串的JS代码,同样也就能够解析JSON格式的字符串,但是解析的时候很不安全,因为字符串里面可能会执行一些恶意代码

 

<span style="font-size:18px;">	var box='[{"title":"one","age":22},{"title":"two","age":35}]';
	alert(box);				//JSON 字符串
	var json = eval(box);	//用eval()方法来解析字符串
	alert(json);			//[object Object],[object Object]	得到原声的JS代码
	alert(json instanceof Array);	//true	解析成功后本来就是字符串套数组
	alert(json[0]);
	alert(json[0].title);	//one
	alert(json[1].age);		//35</span>


全局对象JSON来解析:

全局对象json来进行解析的时候,对浏览器的版本有一定的要求,IE7-就不支持这种解析方式,对于不支持的浏览器也可以通过一个开源库 json.js 来模拟执行,里面就自定义了一个JSON对象【json.js】。全局解析的时候通过JSON对象提供的方法parse()来完成。

直接解析:

直接解析的时候,只是传递一个JSON格式的字符串或者子符文本即可,返回的是原JS代码

<span style="font-size:18px;">	var box='[{"title":"one","age":22},{"title":"two","age":35}]';
	var json = JSON.parse(box);
	alert(typeof json);	//object
	alert(json);	//[object Object],[object Object]
	alert(json[0].title);	//one	解析之后的值
	alert(json[1].age);		//35</span>


接收第二个参数:

第二个参数,是一个函数,可以对解析后的值进行过滤,返回自己想要的值,两个参数代表的是键值对的键和值,对应字典

 

<span style="font-size:18px;">	var box='[{"title":"one","age":22},{"title":"two","age":35}]';
	var json = JSON.parse(box,function(key,value){	//参数名可以改变
		if(key == "title"){	//判断关键字是否是"title"
			return "my is "+value;
		}else if(key== "age"){	//
				return "age="+value;	//这里面可以运算
		}else {
			return value;	//此处不能够做加法元算,会出问题
		}
	});

	alert(json);
	alert(json[0].title);	//my is one
	alert(json[1].title);	//my is two
	alert(json[0].age);		//age=22
	alert(json[1].age);		//age=35</span>


三 序列化JSON数据

 

序列化JSON格式的数据是通过JSON对象提供的方法,JSON.stringify();同样可以接收多个参数,参数一为待解析的字符串,参数二位解析过滤条件,参数三位缩进字符数

原生的JS代码:

 

<span style="font-size:18px;">	var box=[{title:"one",age:22},{title:"two",age:35}];
	alert(box[0].age);	//22</span>


接收一个参数,普通的序列化:

 

 

<span style="font-size:18px;">var box=[{title:"one",age:22},{title:"two",age:35}];
	var json = JSON.stringify(box);
	alert(json instanceof String);	//false
	alert(typeof json);				//string
	//已经被序列化,对象中的键加上了双引号,而且单引号也变成了双引号
	alert(json);	//[{"title":"one","age":22},{"title":"two","age":35}]	</span>


传递第二个参数,进行条件过滤:

参数二传递一个方法:

 

方法中的参数和解析JSON数据中的参数是一样的,两个参数,对应键和值

 

<span style="font-size:18px;">	var box=[{title:"one",age:22},{title:"two",age:35}];
	var json = JSON.stringify(box,function(key,value){
		if(key == "title"){
			return "name:"+value;
		}else if(key == "age"){
			return "age:"+value;
		}else{	//必须要添加这样一个else,否则序列化就不成功
			return value;
		}
	})
	//传递一个方法,改变值,将会序列化了每一个键值对
	alert(json);//[{"title":"name:one","age":"age:22","height":188},{"title":"name:two","age":"age:35","heigth":199}]
</span>


参数二传递一个数组:

 

里面传递要进行序列化的键名,序列化的结果就是只是序列化数组中传递的键名的键值对

 

<span style="font-size:18px;">	var box=[{title:"one",age:22,height:188},{title:"two",age:35,heigth:199}];
	var json = JSON.stringify(box,["title","age"]);
	//上面传递一个数组,结果只是序列化了两个参数
	alert(json);	//[{"title":"one","age":22},{"title":"two","age":35}]</span>


在源JS代码中添加一个方法 toJSON:

 

这个方法,主要是在序列化的时候得到要序列化的内容,它的返回结果就是被序列化的内容,添加了这个方法后,对象中的其它属性字段都不会被序列化,除非在这个方法中写明了要序列的字段,而且添加了这个方法后,序列化的时候传递的第二个参数是不起作用的。

 

<span style="font-size:18px;">	var box=[
		{
			"title":"one",
			"age":22,
			"height":144,
			toJSON:function(){	//方法名必须为toJSON,如果不是这个名称,也不会序列化这个方法
				return this.title+this.height;
			}
		},
		{
			"title":"two",
			"age":23,
			"height":166,
				toJSON:function(){
				return this.title+this.height;
			}
		},
		{
			"title":"three",
			"age":24,
			"height":178,
			toJSON:function(){
				return this.title+this.height;
			}
		}

	]</span>


<span style="font-size:18px;">	var json = JSON.stringify(box)
	//在元数据中添加了一个 toJSON 方法,就只是序列化toJSON中执行的结果,方法名必须为toJSON
	alert(json);	//["one144","two166","three178"]

	var json = JSON.stringify(box,["title"])
	//有了toJSON方法,再传递一个参数就不起作用了
	alert(json);	//["one144","two166","three178"]</span>


参数三:控制格式

 

这个参数表示是否在 JSON 字符串中保留缩进,可以传递一个整形数据,也可以传递其它的符号,比如:*、-

<span style="font-size:18px;">	var box=[{title:"one",age:22,height:188},{title:"two",age:35,heigth:199}];
	var json = JSON.stringify(box,["title","age"],4);
	//序列化的结果中,按照标准格式输出,<span style="color:#ff0000;">执行换行</span>,数字代表每一行相对于上一行应该缩进的距离
	alert(json);	//[{"title":"one","age":22},{"title":"two","age":35}]</span>


第三个参数传递字符的结果:

 

 

<span style="font-size:18px;">	var box=[{title:"one",age:22,height:188},{title:"two",age:35,heigth:199}];
	var json = JSON.stringify(box,["title","age"],"--");
	//用字符串同样的,只是前面用了一个--来标记:</span><span style="color: rgb(255, 0, 0); font-family: Arial, Helvetica, sans-serif; font-size: 18px;">打印的第三行格式为</span><span style="color: rgb(255, 0, 0); font-family: Arial, Helvetica, sans-serif;">:----"title": "one",</span><span style="font-size:18px;">
	alert(json);	//[{"title":"one","age":22},{"title":"two","age":35}]</span>


<span style="font-size:18px;">	var box=[{title:"one",age:22,height:188},{title:"two",age:35,heigth:199}];
	var json = JSON.stringify(box,["title","age"],"*-");
	//也可以,<span style="color:#ff0000;">打印的第三行格式为:*-*-"title": "one",</span>
	alert(json);	//[{"title":"one","age":22},{"title":"two","age":35}]</span>


当第三个参数传递字符的时候,这些字符并不是序列化后的有效JSON数据,仅仅是一个缩进格式而已,也就是将缩进的空白用传递的字符来代替

 

如果不需要对数据进行过滤,但是又想缩进,那么第二个参数写null即可

<span style="font-size:18px;">var box=[{title:"one",age:22,height:188},{title:"two",age:35,heigth:199}];
		var json = JSON.stringify(box,null,"*-");
		//第三行结果为:*-*-"title": "one",
		alert(json);	//[{"title":"one","age":22},{"title":"two","age":35}]</span>



 

从上可以看出,序列化的时候,toJSON方法的执行级别最高,然后是参数二和参数三



 

posted on 2014-05-18 22:43  恋那片海  阅读(272)  评论(0编辑  收藏  举报