JSON的语法可以表示以下三种类型的值
- 简单值:与Javascript中相同的语法,可以在JSON中表示字符串、数值、布尔值和Null。
- 对象:对象作为一种复杂性数据类型,表示的时一组无序的键值对儿。而每对键值的值可以时简单值也可以是复杂数据类型值(对象或数组)
- 数组:数组是一种复杂类型值,表示一组有序的值的列表,可以通过数值索引来访问其中的值,值可以是任何类型的值
简单值
最简单的JSON数据形式就是简单值。
5
:表示数值5
"Hello world"
JSON字符串,与JS不同的是必须使用双引号
对象
JSON的对象与JS中的对象字面量稍微有些不同。
{
"name":"burning",
"age":25
}
首先JSON没有声明变量是因为JSON中没有变量的概念,其次末尾没有分号,并且对象的属性必须加双引号,值可以是简单值也可以使复杂类型值
{
"name":burning,
"age":25,
"friends":{
"goodFriend":"ROTK",
"JustFriend":"Zhou"
}
}
数组
JSON中第二种复杂类型值是数组。JSON采用的就是Javascript中的数组字面量形式。
//JS中的数组
var color=["red","green","black"];
//JSON中的数组
[
{
"title":"professional Javascript",
"author":"Nicholas C.zaka",
"edition":2,
"year":2012
},
{
"title":"Ajex",
"author":"C.zaka",
"edition":2,
"year":2020
}
]
解析与序列化
早期JSON解析器基本上就是使用javascript的eval函数。由于JSON时JavaScript语法的子集,因此eval()函数可以直接解析、解释并返回Javascript对象和数组。JSON对象有两个方法:stringify()和parse(),在最简单的情况下这两个方法分别用于把Javascript对象序列化为JSON字符串和把JSON字符串解析为原生JS
var book={
title:"Ajax",
author:[
"Nicholas c.zakas"
],
edition:3,
year:2012
};
var jsonText=JSON.stringify(book);
console.log(jsonText)
//{"title":"Ajax","author":["Nicholas c.zakas"],"edition":3,"year":2012}
输出的JSON字符串不包含任何空格字符或缩进,我们在有序化Javascript对象的时候,所有函数及原型对象都会被有意忽略。最终的值都是有效的JSON数据类型的实例属性。
我们将JSON字符串传递给JSON.parse()可以得到相应的Javascript值,例如使用以下代码可以创建book类似的对象,使用parse()方法时,大概会启用严格模式,要求传入的参数必须是JSON字符串,之间不能存在换行什么的。。
var JsText='[{"title":"professional Javascript","author":"Nicholas C.zaka","edition":2,"year":2012}, {"title":"Ajex","author":"C.zaka","edition":2,"year":2020}]';
var book={
title:"Ajax",
author:[
"Nicholas c.zakas"
],
edition:3,
year:2012
}
var jsonText=JSON.stringify(book);
console.log(jsonText);
console.log(JSON.parse(JsText));
序列化骚操作
实际上,JSON.stringify()
除了要序列化的Javascript对象外,还可以接受两个参数,第一个参数是个过滤器,可以是一个数组,也可以是一个函数;第二个参数是一个选项,表示是否在JSON字符串中保留缩进。
var book={
title:"Ajax",
author:[
"Nicholas c.zakas"
],
edition:3,
year:2012
}
var jsonText=JSON.stringify(book,["author","year"]);
console.log(jsonText);//{"author":["Nicholas c.zakas"],"year":2012}
如上,第二个参数时一个数组,包含两个字符串,那么在返回的结果中,就只会包含这两个属性,如果第二个是函数,那么行为会有些不同,传入的函数接收两个参数,第一个是键名,第二个时键值(*我们在筛选器中要是放入嵌套属性也会被过滤掉)
var book={
title:"Ajax",
author:[
"Nicholas c.zakas"
],
edition:3,
year:2012
}
var jsonText=JSON.stringify(book,function(key,value){
switch(key){
case "title":
return value.concat("hello");
break;
case "author":
value.push("burning");
value.splice(1,0,"ROTK")
return value
break;
case "edition":
return value+1;
break;
case "year":
return value+10;
break;
default:
return value;
}
},4);
console.log(jsonText);
//输出结果如下
{
"title": "Ajaxhello",
"author": [
"Nicholas c.zakas",
"ROTK",
"burning"
],
"edition": 4,
"year": 2022
}
设置的第三个参数为4,表示每个级都有4个空格符的缩进,并且自动包含换行符,最大缩进为10,大于10会自动转换为10。但是并没有规定第三个参数的类型,我们可以按照我们想要的缩进符号进行缩进,比如”….”或者”QAQ”,这个自行尝试
toJSON()
有时候,JSON.stringify()并不能满足某些对象进行自定义序列化的需求,在某些情况下,可以给对象定义toJSON()方法,返回其自身的JSON的数据格式。原生Date对象有一个toJSON()方法,能够将javascript的Date对象自动转换成ISO 8601日期字符串,与在Date()对象上调用toISOString()方法一样,*此方法优先级最高
var book={
title:"Ajax",
author:["Nicholas"],
name:{
firstName:"jack",
last:"peter"
},
edition:3,
year:2012,
toJSON:function(){
return this.title
}
}
var jsonText=JSON.stringify(book,null,"-3-3");
console.log(jsonText)//只会得到Ajax
解析选项
JSON.parse()可以接收另一个参数,是一个函数,将在每个健对上调用。为了区别过滤函数,则个函数被成为还原函数,都接收key值和value值。如果还原函数返回undefined则表示从结果中删除相应的键值,如果返回其他只则插入进结果中
var book={
title:"Ajax",
author:["Nicholas"],
name:{
firstName:"jack",
last:"peter"
},
edition:3,
year:2012,
rel:new Date(2011,1,1)
}
var jsonText=JSON.stringify(book);
var bookcopy=JSON.parse(jsonText,function(key,value){
if (key==="rel") {
// return new Date(value);
return undefined;
}else{
return value;
}
})
console.log(bookcopy)