JSON

json的应用早在2001年就已经开始了,JSON是JavaScript的一个严格的子集,利用JavaScript中的一些模式来表示结构化数据。JSON是一种数据格式,不是一种编程语言,虽然具有相同的语法形式,但JSON并不从属于JavaScript。

一、语法

json的语法可以表示一下三种类型的值

  • 简单值:可以在JSON中表示字符串、数值、布尔值和null,但JSON不支持JavaScript中的特殊值undefined
  • 对象
  • 数组
    例如:json数据格式
{
    "name":"anxiaoyan",
    "age":22,
    "school":{
        "name":"NWAFU",
        "location":"shanxi·china"
    },
    "hobby":[
    "reading",
    "game",
    "sports"
    ]
}

二、Json解析和序列化

JSON之所以流行,拥有与JavaScript类似的语法并不是全部的原因。更重要的一个原因是,可以把JSON数据结构解析为有用的JavaScript对象。
JSON对象有两个方法:stringify()和parse(),这两个方法分别用于将JavaScript对象序列化成json字符串和把json字符串解析为原生的JavaScript值。

2.1JavaScript序列化成json字符串

例如:

var book = {
    title:"Professional javascript",
    authors:[
        "Nicholas C.Zakas"
    ],
    edition:3,
    year:2011
};
var jsonText = JSON.stringify(book);

结果显示保存在jsonText中的字符串的格式如下所示:

{"title":"Professional javascript","authors":["Nicholas C.Zakas"],"edition":3,"year":2011}

注意:在序列化JavaScript对象时,所有函数及原型成员都会被有意忽略,不体现在结果中,,此外值为undefined的任何属性也都会被跳过,结果最终都是值为有效的json数据类型的实例属性。

2.2Json字符串解析为JavaScript对象

将JSON字符串直接传递给JSON.parse()就可以得到相应的JavaScript值

var bookCopy = JSON.parse(jsonText);

返回结果与book具有相同的属性,但是他们是两个相互独立的,没有任何关系的对象。
如果传给JSON.parse()的字符串不是有效的json,该方法就会抛出错误

2.3序列化选项

JSON.stringify()除了要序列化的JavaScript对象之外,它还可接收另外两个参数,这两个参数用于指定以不同方式序列化JavaScript对象,第一个参数是个过滤器,可以是一个数据,也可以是一个函数。第二个参数是一个选项,表示是否在JSON字符串中保留缩进,单独或组合使用这两个参数,可以更加全面的控制JSON的序列化。

2.3.1过滤结果

  • 如果过滤参数是个数组,那么JSON.stringify()的结果中只包含数组中列出的属性。例如:
var book = {
    title:"Professional javascript",
    authors:[
        "Nicholas C.Zakas"
    ],
    edition:3,
    year:2011
};
var jsonText = JSON.stringify(book,["title","edition"]);

console.log(jsonText);

JSON.stringify()第二个参数是一个数组,其中包含“title”和“edition”,这两个属性将要序列化的对象中的属性是对应的,因此在返回结果中,只包含这两个属性

{"title":"Professional javascript","edition":3}
  • 如果第二个参数是一个函数,传入的函数接收两个参数,key和value,根据属性键名可以知道应该如何处理要序列化的对象中的属性,属性名只能是字符串,而在值并非键值对结构的值时,键名可以是空字符串,为了改变序列化对象的结果,函数返回的值就是相应键的值,不过注意,如果函数返回了undefined,那么相应的属性会被忽略。例如:
var book = {
    title:"Professional javascript",
    authors:[
        "Nicholas C.Zakas"
    ],
    edition:3,
    year:2011
};
var jsonText = JSON.stringify(book,function(key,value){
    switch(key){
        case "authors":
            return value.join(",");
        case "year":
            return 5000;
        case "edition":
            return undefined;
        default:
            return value;
    }
});

console.log(jsonText);

如果键为authors,就将数组连接为一个字符串,如果键为“year”,将其值设为5000,如果键为“edition”,通过返回undefined删除该属性。
序列化之后的JSON字符串为

{"title":"Professional javascript","authors":"Nicholas C.Zakas","year":5000}

2.4字符串缩进

JSON.stringify()的第三个参数用于控制结果中的缩进和空白符.

  • 如果这个参数是一个数值,那它表示的是每个级别缩进的空格数,例如:要求每个级别缩进四个空格,代码如下:
var jsonText = JSON.stringify(book,null,4)

保存在jsonText中的字符串如下所示:

{
    "title": "Professional javascript",
    "authors": [
        "Nicholas C.Zakas"
    ],
    "edition": 3,
    "year": 2011
}
  • 如果缩进参数是一个字符串而非数值,则这个字符串将在json字符串中被用作缩进字符(不再使用空格),例如:
var jsonText = JSON.stringify(book,null,"- -");

这样,jsonText中的字符串将变成如下所示:

{
- -"title": "Professional javascript",
- -"authors": [
- -- -"Nicholas C.Zakas"
- -],
- -"edition": 3,
- -"year": 2011
}

注意:缩进字符串最长不能超过10个字符,如果字符串长度超过了10个,结果中将只出现前10个字符

2.4 toJSON()方法

有时候,JSON.stringify()还是不能满足对某些对象进行自定义序列化的需求,在这些情况下可以对象定义toJSON()方法,返回其自身的JSON数据格式。可以为任何对象添加toJSON()方法,例如:

var book = {
    title:"Professional javascript",
    authors:[
        "Nicholas C.Zakas"
    ],
    edition:3,
    year:2011,
    toJSON:function(){
        return this.title;
    }
};
var jsonText = JSON.stringify(book);

以上book对象定义了toJSON()方法,所以JSON.stringify()返回结果如下:

"Professional javascript"

注意:当toJSON()方法返回undefined,此时如果包含它的对象嵌入在另外一个对象,会导致它的值变为null,如果它是顶级对象,结果就是undefined。
toJSON()可以作为函数过滤器的补充,因此理解序列化的内部顺序十分重要。假设把一个对象传入JSON.stringify()序列化该对象的顺序如下:

(1) 如果存在toJSON()方法而且能通过它取得有效的值,则调用该方法。否则,返回对象本身。
(2)如果提供了第二个参数,应用这个函数过滤器。传入函数过滤器的值是第(1)步返回的值
(3)对第(2)步返回的每个值进行相应的序列化
(4)如果提供了第三个参数,执行相应的格式化。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容