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方法的执行级别最高,然后是参数二和参数三