JSON

一、语法

JSON语法可以表示以下三种类型的值:

1)简单值:字符串,数值,布尔值和null。不支持undefined;

2)对象:一组无序的键值对儿。每个键值对儿中的值可以是简单值也可以是复杂数据类型的值。

3)数组:一组有序的值得列表,可以通过数值索引来访问其中的值。数组的值也可以是任意类型——简单值、对象或数组。

 

1. 简单值

5  “Hello world!”

JS字符串与JSON字符串的最大区别在于,JSON字符串必须使用双引号(单引号会导致语法错误)。

布尔值和null也是有效的JSON形式。

 

2. 对象值

{
    “name”:”Nicholas”,
    “age”:29
}

 

与JS的对象字面量相比,JSON对象有两个地方不一样。首先,没有声明变量(JSON中没有变量的概念)。其次,没有末尾的分号对象的属性必须加双引号,这在JSON中是必需的。属性的值可以是简单值也可以是复杂类型值,因此可以像下面这样在对象中嵌入对象:

{
    “name”:”Nicholas”,
    “age”:29,
    “school”:{
        “name”:”Merrimack”,
        “location”:”North”
  }
}

 

 

3. 数组

JSON中的第二种复杂数据类型是数组。JSON数组采用的就是JS中的数组字面量形式。

[25,”hi”,true]

JSON数组也没有变量和分号。把数组和对象结合起来,可以构成更复杂的数据集合。

 

二、解析与序列化

1.JSON对象

早期的JSON解析器基本上就是使用JS的eval()函数。由于JSON是JS语法的子集,因此eval()函数可以解析、解释并返回JS对象和数组

JSON对象有两个方法:stringify()和parse()。分别用于把JS对象序列化为JSON字符串和把JSON字符串解析为原生JS值。

1)JSON.stringify()把JS对象序列化为JSON字符串

var book={
     title:”Professional”,
     authors:[“Nic”],
     edition:3,
     year:2011
};
var jsonText=JSON.stringify(book);

 

默认情况下,JSON.stringify()输出的JSON字符串不包含任何空格字符或缩进,因此保存在jsonText中的字符串如下:

{“title”:”professional”,”authors”:[“Nic”],”edition”:3,”year”:2011}

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

 

2) JSON.parse()把JSON字符串解析为原生JS值

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

var bookCopy=JSON.parse(jsonText);

如果传给JSON.parse()的字符串不是有效的JSON,该方法会抛出错误。

 

2. 序列化选项

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

1)过滤结果

如果过滤参数是数组,那么JSON.stringify()的结果中将只包含数组中列出的属性。

var book={
    "title":"Profess",
    "author":["Nic"],
    edition:3,
    year:2011
};
var jsonText=JSON.stringify(book,["title","edition"]); //{“title”:”Profess”,”edition”:3}

 

如果传入的是函数,行为稍有不同。传入的函数接收两个参数,属性名和属性值。根据属性名可以知道应该如何处理要序列化的对象中的属性。属性名只能是字符串,而在值并非键值对儿结构的值时,键名可以是空字符串。为了改变序列化对象的结果,函数返回的值就是相应键的值。但是如果函数返回了undefined,那么相应的属性会被忽略

var book={
      “title”:”Profess”,
      “author”:[“Nic”,”Mary”],
       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;
  }
})
//输出
{“title”:”Profess”,”authors”:”Nic.Mary”,”year”:5000}

 

最后一定要提供default项,此时返回传入的值,以便其他值都能正常出现在结果中。实际上,第一次调用这个函数过滤器,传入的键是一个空字符串,而值就是book对象。

 

2) 字符串缩进

JSON.stringify()方法的第三个参数用于控制结果中的缩进和空白符。如果这个参数是一个数值,那他表示的是每个级别缩进的空格数。

如上例: var jsonText=JSON.stringify(book,null,4);

保存在jsonText的字符串如下:

{

         “title”:”Profess”,

         “authors”:[“Nic”,”Mary”],

         “edition”:3,

         “year”:2011

}

只要传入有效的控制缩进的参数值,结果字符串就会包含换行符。(只缩进而不换行意义不大)。最大缩进空格数为10,所有大于10的值都会自动转换为10.

如果缩进参数是一个字符串而非数值,则这个字符串将在JSON字符串中被用作缩进字符(不再使用空格)。在使用字符串的情况下,可以将缩进字符设置为制表符,或者两个短划线之内的任意字符。

var jsonText=JSON.stringify(book,null,”--”);

缩进字符串最长不能超过10个字符长。如果字符串长度超过了10个,只出现前10个字符。

 

3)toJSON()方法

可以为任何对象添加toJSON()方法

var book={
      "title":"Profess",
      "authors":['Nic','Mary'],
       edition:3,
       year:2011,
       toJSON:function(){
              return this.authors;
       }
 }                
var jsonText=JSON.stringify(book);
alert(jsonText); // [‘Nic’,’Mary’]

 

toJSON()可以作为函数过滤器的补充,因此理解序列化的内部顺序十分重要。假设把一个对象传入JSON.stringify(),序列化该对象的顺序如下

1)如果存在toJSON()方法而且通过它可以取得有效的值,则调用该方法。否则返回对象本身。

2)如果提供了第二个参数,应用这个函数过滤器。传入函数过滤器的值是第(1)步返回的值。

3)对第2)步中返回的每个值进行相应序列化

3)如果提供了第三个参数,执行相应格式化

 

3.解析选项

JSON.parse()也可以接受另一个参数,该参数是一个函数,将在每个键值对儿上调用。这个函数被称为还原函数。它们都接受两个参数,一个键和一个值,而且都需要返回一个值。

如果还原函数返回undefined,则表示要从结果中删除相应的键;如果返回其他值,则将该值插入到结果中。在将日期字符串转换为Date对象时,经常要用到还原函数。

var book={
     "title":"Profess",
     "authors":['Nic','Mary'],
     edition:3,
     year:2011,
     releaseDate:new Date(2011,11,1)
}                
var jsonText=JSON.stringify(book);
alert(jsonText);
var bookCopy=JSON.parse(jsonText,function(key,value){
      if(key=='releaseDate'){
            return new Date(value);
       }else{
            return value;
      }
});
alert(bookCopy.releaseDate.getFullYear());

 

posted @ 2016-05-18 22:06  爆炒小黄鸡  阅读(201)  评论(0编辑  收藏  举报