JSON语法和js类似,所以在使用上JavaScript开发者能够快速上手JSON
而且通过JSON获取数据很方便,不像js那样繁琐
JSON对象方法
方法有两个:
- JSON.stringify():JavaScript转化为不包含空格和缩进的JSON字符串
- JSON.parse(); JSON解析为原生JavaScript值,其中的函数和原型对象在解析时会被省略,值是undefined的属性会被跳过解析,最终得到的值都能够在js中正常运行
一般情况下都是通过这两个方法将JavaScript转化为JSON字符串,然后再将JSON解析为JavaScript字符串
当然JSON.parse()可以将转化的JavaScript值来赋值给一个变量,达到深拷贝的效果
序列化选项
JSON.stringify()方法除了将js对象转为JSON字符串,还可以同时接收两个参数
- 第一个参数为过滤器,可以是函数或数组
- 第二个是缩进选项
过滤结果
如果为数组则JSON.stringify()返回的结果只会包含该字符串中列出的对象属性
let person = {
name = "wangmou",
age= 23,
school:{
name:"college",
location:"hubei wuhan,ZH"
},
edition:4,
year : 2020
};
let jsonText = JSON.stringify(person,["name","edition"]) //{"name":"yuanmou","edition":4}
添加了第一个过滤器参数后,只会将其中包含的对象属性进行JSON序列化
如果为函数则会给函数提供两个参数:
- 属性名(key)
- 属性值 (value)
let person = {
name: "xiaoba",
skill: [
"Vue",
"wxproject"
],
edition: 4,
year: 2020
};
let jsonText = JSON.stringify(book, (key, value) => { //函数为筛选器
switch(key) {
case "skill":
return value.join(",") //筛选到skill时将其转化为以,间隔的字符串
case "year":
return 40; //筛选到year时,返回40
case "edition":
return undefined; //由于JSON没有underfined,所以返回会忽略这个属性
default:
return value; //其他属性原样返回
}
});
//{"name":"xiaoba","skill":"Vue,wxproject","year":40}
注意,函数过滤器过滤的是当前转换对象的内部所有属性,如果是由多个对象组成的数组,则数组中每个对象只会剩下过滤器过滤后的内容
字符串缩进
第二个参数控制缩进和空格,如果这个参数为数值时表示每一级缩进的空格数
let person = {
name: "zhangmou",
skill: [
"Vue",
"wxproject"
],
edition: 4,
year: 2020
};
let jsonText = JSON.stringify(person,null,4) //第一个参数不用也需要写出来空着!!
结果就是
{
"name":"zhangmou", //当前一级前面多4个空格
"skill":[
"Vue", //下一级在当前级的基础上再多4个空格
"wxproject"
],
"edition":4,
"year":2020
}
除了缩进空格,还能插入换行符方便阅读, 最大缩进为10,如果大于10会自动设置为10
如果,缩进参数不是数值,而是一个字符串,则会将空格替换成这个字符串进行缩进
let jsonText = JSON.stringify(person,null,"_*_") //第一个参数不用也需要写出来空着!!
将空格换成”*“来进行缩进结果就是
{
_*_"name":"zhangmou", //当前一级前面多4个空格
_*_"skill":[
_*__*_"Vue", //下一级在当前级的基础上再多4个空格
_*__*_"wxproject"
],
_*_"edition":4,
_*_"year":2020
}
字符串也有长度限制,最大为10个字符
toJSON()方法
自定义JSON序列化,在要序列化的对象中添加一个toJSON()方法,转化为JSON对象时会基于这个方法返回JSON对象
let person = {
name: "zhangmou",
skill: [
"Vue",
"wxproject"
],
edition: 4,
year: 2020,
toJSON:function(){ //偷偷的创建一个toJSON()方法
return this.name;
}
};
let jsonText = JSON.stringify(person)
console.log(jsonText) //"zhangmou"
返回一个简单字符串,虽说啥参数也没加,但是内部自定义的toJSON方法限制只会返回name的属性值转化为JSON字符串
toJSON()方法可以返回任意序列化值,都可以起到相应的作用。如果对象被嵌入在另一个对象中,返回 undefined 会导致值变成 null;或者如果是顶级对象,则本身就是 undefined。
这个方法可以和过滤函数(第一个参数设置为函数)一起使用因此理解不同序列化流程的顺序非常重要。在把对象传给 JSON.stringify()时会执行如下步骤:
1. **如果可以获得实际的值,就先用toJSON()方法获得实际的值,没有就使用JSON.stringify()**
1. **如果JSON.stringify()里有第一个参数(过滤数组或函数),则执行第一步的结果传入第二步**
1. **接下来将传入JSON.stringify()里过滤出的对象进行序列化(转化为JSON对象)**
1. **如果还添加了第二个参数(缩进和空格),则再将转化的JSON对象进行对应的缩进**
解析选项
JSON.parse()方法也能接收一个额外的参数,这时函数会对每一个JSON对象的键值对都调用一次,与JSON。stringify()方法的第一个参数格式完全一样
如果函数返回undefined则会删除这个键(对象的属性名),如果返回其他任何值(只要不是undefined都行)他都会将相应的键的值插入到转化完JavaScript对象的属性值上
let person = {
name: "zhangmou",
skill: [
"Vue",
"wxproject"
],
edition: 4,
year: 2020,
onDate:new Date(2021,6,18)
};
let jsonText = JSON.stringify(person);
let personCopy = JSON.parse(jsonText,(key,value)=>key == onDate(value) : value);
alert(personCopy.onDate.getFullYear());
以上代码在 person对象中增加了 onDate属性,是一个 Date 对象。这个对象在被序列化为JSON 字符串后,又被重新解析为一个对象 personCopy。这里的还原函数会查找”onDate”键,如果找到就会根据它的日期字符串创建新的 Date 对象。得到的 personCopy.onDate 属性又变回了Date 对象,因此可以调用其 getFullYear()方法。