目录
语法(JSON可以表示的值类型)
- 简单值
在json中表示字符串,数值,布尔值和null。
eg:”hello world”
注意:json中所有的字符串,包括其它用到引号的地方,统一使用双引号。
- 对象
复杂数据类型,表示的是无序的键值对,对象的属性的值也可以是多种类型,简单类型,对象类型,数组类型。
注意:对象的json格式数据,1.没有声明变量,2.属性是带双引号的,3.json对象的末尾没有分号。
Eg:
{
“name”:”赵”,
“age”:18,
}
- 数组
复杂数据类型,表示的是有序的值的列表,而数组列表里的值也可以是简单值,对象或是数组。
数组也没有声明变量和分号。其余的与数组形式相同,注意双引号。
- 定义
Json是一种用于数据传输的数据格式,表示结构化数据的格式。
Json并不支持变量、实例化或者函数,它与js的语法相似,但是是很多语法和地方通用的,并不是局限在js上的。
解析与序列化
解析就是将json数据结构解析为js可以使用的js对象,比xml数据结构方便,xml数据结构会解析成一个dom文档,再从中解析数据,很麻烦。
序列化:1. 将js对象序列化为一个json字符串,并将它保存在jsonText中。
2. 将json字符串序列化为js对象。
JSON对象
早期:使用eval(),eval()可以解析并返回js数组或对象。
现阶段:使用JSON.stringfy()或JSON.parse()。
为什么淘汰eval()?
因为eval()并不安全,在使用eval()进行json的解析时,在进行数据结构求值时并不会检查解析的东西是否符合json的格式,也就是没有安全检查,可以在值得部分写任意东西,例如js的语句,这种植入可能是恶意代码。
但如果使用JSON.parse()就可以进行自动检查。
JSON.stringfy()
使用JSON.stringify()将js对象、简单值、数组序列化成json字符串。
-
基本语法(参数设置)
JSON.stringify()共有三个参数:
- 需要转化成json字符串的js对象。
- 过滤器(过滤函数):
一个数组:数组的值就是需要转化成json字符串的对象的属性名。
一个函数:传入函数接受两个参数:属性名和属性值,属性名对应的就是js对象中的属性名,属性值就是js对象中各属性名对应的属性值。
属性名只能是字符串,若不是键值对的形式时,属性名可以是空字符串。
eg:在函数中,先匹配属性名,再在匹配成功的地方对属性值调用此处的函数语句。
<script>
var book={
"title":"Professioal JavaScript",
"authors":["Nike"],
"editor":3,
"year":2011
};
var jsonText=JSON.stringify(book,function(key,value){
switch(key){
case "title":
return value.join(",");
case "year":
return 5000;
case "editor":
return undifined;
default:
return value;
}
//序列化后,json字符串为:
{"title":"Professioal JavaScript","authors":"Nike","year":5000}
})
</script>
注意:当值为undifined的时候,这个键值对就将被筛掉,同样的,当函数返回undefined时,相应的属性也会被忽略掉。
不使用这个过滤器,就填null。
3. 字符串缩进
控制结果中的缩进以及空白符。
参数为数字:表示空白格的缩进,数字是几就表示缩进几个。
var book = {
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
edition: 3,
year: 2011
};
var jsonText = JSON.stringify(book, null, 4);
保存在 jsonText 中的字符串如下所示:
{
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
"edition": 3,
"year": 2011
}
参数为字符:将这个字符作为缩进字符,空格就不再使用了。可以将缩进字符设置为制表符,或者其它字符。
var jsonText = JSON.stringify(book, null, " - -");
保存在 jsonText 中的字符串如下所示:
{
--"title": "Professional JavaScript",
--"authors": [
----"Nicholas C. Zakas"
--],
--"edition": 3,
--"year": 2011
}
注意:当设置为数字(空白格个数)时,如果超过10将只显示十个;当设置为特定字符时,缩进字符串的长度不能超过10,超过的话只显示前10个。
-
toJSON()方法
有时,JSON.stringify()并不能满足对某些对象进行自定义序列化的需求,这时,可以给对象使用toJSON()方法,返回其自身的JSON格式数据。然后再使用JSON.stringify()。
可以让toJSON()返回任何值,它都可以正常工作,也不会影响使用它的对象工作。例如:如果一个对象包含的子对象在使用了toJSON()后,子对象的返回值是undefined,那么,在这个对象中,也只是它的值变成了null,并不会还是underfined,从而导致被过滤。
但是,如果是顶级对象使用toJSON()返回undefined时,那就会被过滤。
toJSON()的加入,让序列化的过程和过滤的过程变得更加复杂,所以,需要进行进一步分析序列化的顺序才能得到正确的序列化JSON字符串。
-
序列化的顺序
假设把一个js对象传入JSON.stringify(),序列化的顺序如下:
- 先判断是否存在toJSON(),存在此方法且取到了有效值,则先调用它,否则返回对象本身。
- 将1中的处理结果,即1的返回值,用JSON.stringify()的第二个参数处理,即过滤器处理。
- 对2的结果进行序列化。
- JSON.stringify()的第三个参数处理3的结果,即对序列化的JSON字符串的缩进进行处理。
JSON.parse()
JSON.parse()将json字符串转为js对象。
JSON.parse(),有两个参数。
- 变量名:第一个参数是要转为js对象的json赋值的变量的变量名。例如这里的jsonText。
var jsonText=JSON.stringify(book,null,0);
当然,这里的jsonText可以是接收的json字符串,这里只是举例。
- 还原函数:第二个参数是一个函数,在json字符串的每个键值对上都会调用它。这个函数被称作还原函数。如果还原函数的返回值是undefined,那在结果中就要删除相应的键,如果返回其它值,就将该值插入到结果中。
eg:将日期字符串还原为Date对象。
var book = {
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
edition: 3,
year: 2011,
releaseDate: new Date(2011, 11, 1) //含有日期对象
};
var jsonText = JSON.stringify(book); //转为json字符串,对象形式不存在了
var bookCopy = JSON.parse(jsonText, function(key, value){
if (key == "releaseDate"){
return new Date(value); //将日期转化为js对象时,转换成Date对象
} else {
return value;
}
});
alert(bookCopy.releaseDate.getFullYear());//转换成Date对象,才能使用getFullYear()属性
总结
Json是轻量级的数据格式,简化了表示复杂数据结构的工作量。比使用xml更加简便,因为它并不需要再从xml形成的dom文档再查找想要的数据。
而ES5定义了原生的JSON对象,可以满足将对象序列化成json字符串,或将json字符串解析成js对象的功能,他们分别对应JSON.stringify()和JSON.parse(),并且使用这些方法,可以满足过滤或还原的需求。
欢迎大家在评论区留言、补充、错误指正~~~~