关于JSON的三点理解:
JSON是JS的一个严格的子集,是JS的两大内置对象之一(ES5定义了全局对象JSON)。
利用JS中的一些模式来表示结构化数据,JSON是数据格式,而不是一种编程语言。
值得注意的是JSON并不从属于JS,并不是只有JS才使用JSON,很多语言对JSON都有解析器和序列化器。
JSON的语法:
JSON的语法可以表示以下三种类型的值:
- 简单值:JSON可以表示字符串、数字、布尔值和null。
- 对象。
- 数组。
JSON的语法不支持JS语法中的有:
- 不支持JS中的特殊值undefined。
- 不支持JS中的变量、函数或对象实例。
下面都是有效的JSON数据:
- 简单值——数值
5
- 简单值——字符串
JSON字符串必须使用双引号,单引号会导致语法错误。
"Hello world!"
- 简单值——布尔值
true
- 简单值——null
null
- 对象
一、JSON没有变量的概念,所以没有声明变量;
二、没有末尾分号;
三、JSON对象属性必须加双引号;
{
"firstName":"Qingke",
"lastName":"Zhao"
}
- 数组
一、JSON数组没有变量;
二、JSON数组没有分号;
[1,"string",true,[2,4],{"name":"zhaobiyang"}]
JSON对象的API——解析与序列化
JSON对象有两个方法:stringify() && parse()
一、stringify()
用于把JS对象序列化为JSON字符串,有三个参数,第一个参数是被序列化的对象,第二个参数是个过滤器,第三个参数是一个选项。
1.第二个参数(过滤器):可以是一个数组,也可以是一个函数。
a、数组:如果是数组,那么JSON.stringify()的结果中将只包含数组中列出的属性
var book={
"title":"JavaScript",
"authors":[
"ZhaoBiyang"
],
year:2018
}
var jsonText=JSON.stringify(book,["authors","year"]);
console.log(jsonText);//{"authors":["ZhaoBiyang"],"year":2018}
b、函数:如果是函数,函数接收两个参数,属性名(键)和属性值(值),属性名必须是字符串,而在值并非键值对儿结构的值时,键名可以是空字符串。函数返回的值是相应的键的值,但是,如果函数返回的是undefined,相应的属性会被忽略(删除该属性)
var book={
"title":"JavaScript",
"authors":[
"ZhaoBiyang","changshanshan"
],
edition:3,
year:2018,
name:function(){
alert("ok")
}
}
var jsonText=JSON.stringify(book,function(key,value){
switch(key){
case "authors":
return value.join(",");
case "year":
return 1992;
case "edition":
return undefined;
default:
return value;
}
});
2、第三个参数(字符串缩进):
a、如果这个参数是一个数值,它表示的是每个级别缩进的空个数,只要传入有效的控制缩进的参数值,结果字符串就会包括换行符(只缩进不换行意义不大);最大缩进空格数为10,所有大于10的值都会转换为10。
b、如果参数是一个字符串而非数值,则这个字符串会在JSON字符串中被用作缩进字符,不能超过10字符长,超过的话,只出现前10个字符。
var book={
"title":"JavaScript",
"authors":[
"ZhaoBiyang","changshanshan"
],
edition:3,
year:2018,
name:function(){
alert("ok")
}
}
var jsonText=JSON.stringify(book,null,"--");
/*
jsonText中的字符串就会变成下面的样子:
{
--"title":"JavaScript",
--"authors":[
----"zhaobiyang","changshanshan"
--],
--"edition":3,
--"year":2018
}
*/
3、toJSON()方法:
某些情况下JSON.stringify()不能满足序列化需求,可以给要序列化的对象定义toJSON()方法,返回其自身的JSON数据格式,原生的Date对象有一个toJSON()方法,返回ISO8601日期字符串(与在Date对象上调用toISOString()的结果完全一样)。
可以为任意对象添加toJSON()方法:
var book={
"title":"zhao",
"name":"beyond",
toJSON:function(){
return this.name;
}
}
var jsonText=JSON.stringify(book);
console.log(jsonText)
/*
"beyond"
*/
可以让toJSON()方法返回任何值,他都能正常工作。比如可以让这个方法返回undefined,此时如果包含它的对象在另一个对象中,会导致包含它的对象变为null,如果它是顶级对象,值就是undefined。
toJSON()可以作为函数过滤器的补充,因此理解序列化的内部顺序十分重要。假设把一个对象传入JSON.stringify(),序列化该对象的顺序如下:
(1)如果存在toJSON()方法,且能够通过它返回有效的值,则调用该方法。否则返回对象本身。
(2)如果提供第二个参数,应用这个函数过滤器,传入函数的值是第(1)步的返回值。
(3)对第(2)返回的每个值进行相应的序列化。
(4)如果存在第三个参数,执行相应的格式化。
二、parse()
用于把 JSON字符串解析为原生JS值。有两个参数,第一个参数为JSON字符串,第二个可选参数为还原函数,和序列化的过滤函数类似,传入还原函数的参数为一个键一个值,而且都需要返回一个值。
如果还原函数返回undefined,则表示要从结果中删除相应的键;如果返回其他值,则将该值插入到结果中。在将日期字符串转换为Date 对象时,经常要用到还原函数。例如:
var book={
"title":"JavaScript",
"authors":[
"nick","lining"
],
edition:3,
year:2011,
releaseDate:new Date(2011,11,1)
}
var jsonText=JSON.stringify(book);
var bookCopy=JSON.parse(jsonText,function(key,value){
if(key=="releaseDate"){
return new Date(value)
} else {
return value;
}
})
console.log(bookCopy);
//{title: "JavaScript", authors: Array(2), edition: 3, year: 2011, releaseDate: Thu Dec 01 2011 00:00:00 GMT+0800 (中国标准时间)}
欢迎指正。。。