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 = "yuanmou",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: "yuanmou",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时,返回40case "edition":return undefined; //由于JSON没有underfined,所以返回会忽略这个属性default:return value; //其他属性原样返回}});//{"name":"yuanmou","skill":"Vue,wxproject","year":40}
注意,函数过滤器过滤的是当前转换对象的内部**所有属性,**如果是由多个对象组成的数组,则数组中每个对象只会剩下过滤器过滤后的内容
字符串缩进
第二个参数控制缩进和空格,如果这个参数为数值时表示每一级缩进的空格数
let person = {name: "yuanmou",skill: ["Vue","wxproject"],edition: 4,year: 2020};let jsonText = JSON.stringify(person,null,4) //第一个参数不用也需要写出来空着!!
结果就是
{"name":"yuanmou", //当前一级前面多4个空格"skill":["Vue", //下一级在当前级的基础上再多4个空格"wxproject"],"edition":4,"year":2020}
除了缩进空格,还能插入换行符方便阅读, 最大缩进为10,如果大于10会自动设置为10
如果,缩进参数不是数值,而是一个字符串,则会将空格替换成这个字符串进行缩进
let jsonText = JSON.stringify(person,null,"_*_") //第一个参数不用也需要写出来空着!!
将空格换成”*“来进行缩进结果就是
{_*_"name":"yuanmou", //当前一级前面多4个空格_*_"skill":[_*__*_"Vue", //下一级在当前级的基础上再多4个空格_*__*_"wxproject"],_*_"edition":4,_*_"year":2020}
字符串也有长度限制,最大为10个字符
toJSON()方法
自定义JSON序列化,在要序列化的对象中添加一个toJSON()方法,转化为JSON对象时会基于这个方法返回JSON对象
let person = {name: "yuanmou",skill: ["Vue","wxproject"],edition: 4,year: 2020,toJSON:function(){ //偷偷的创建一个toJSON()方法return this.name;}};let jsonText = JSON.stringify(person)console.log(jsonText) //"yuanmou"
返回一个简单字符串,虽说啥参数也没加,但是内部自定义的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: "yuanmou",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()方法。
