JSON语法和js类似,所以在使用上JavaScript开发者能够快速上手JSON

而且通过JSON获取数据很方便,不像js那样繁琐


JSON对象方法

方法有两个:

  1. JSON.stringify():JavaScript转化为不包含空格和缩进的JSON字符串
  2. JSON.parse(); JSON解析为原生JavaScript值,其中的函数和原型对象在解析时会被省略,值是undefined的属性会被跳过解析,最终得到的值都能够在js中正常运行

一般情况下都是通过这两个方法将JavaScript转化为JSON字符串,然后再将JSON解析为JavaScript字符串

当然JSON.parse()可以将转化的JavaScript值来赋值给一个变量,达到深拷贝的效果


序列化选项

JSON.stringify()方法除了将js对象转为JSON字符串,还可以同时接收两个参数

  1. - 第一个参数为过滤器,可以是函数或数组
  2. - 第二个是缩进选项

过滤结果

如果为数组则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时,返回40
 case "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()方法。