JSON

JSON是javascript的一个严格的子集,但它不支持变量、函数或对象实例,它是一种表示结构化数据的格式。

语法

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

  • 简单值:字符串、数值、布尔值和null。不支持undefined;
  • 对象:对象的属性值可以是简单值,也可以是对象或数组;
  • 数组:数组的值也可以是任意类型——简单值、对象或数组。

简单值

最简单的JSON数据形式就是简单值,但是它一般只作为整个数据结构的一部分。

下面这些,都是有效的JSON数据:

5
"hello"

注意:JSON字符串必须使用双引号,单引号会导致语法错误。

对象

JSON可以这样表示:

{
   "name":"Bob",
   "age":12
}

注意,它与javascript对象字面量有以下三点不同:

  1. 没有变量声明(JSON中没有变量的概念);
  2. 在{}的末尾没有用分号结束(它不是javascript语句,所以不需要分号);
  3. JSON对象中的属性必须加双引号!

JSON属性的值可以是简单值,也可以是复杂类型值:

{
          	"name":"Bob",
          	"age":12,
          	"school":{
          		"name":"schoolname",
          		"location":"FJ"
          	}
}

数组

JSON数组就是采用javascript的数组字面量形式:

[25,"hello",true]

同样注意,JSON数组也没有变量和分号。

把数组跟对象结合起来,便会构成更复杂的数据结构:

[
               {
               	"title":"title1",
               	"authors":[
               	   "author1"
               	],
               	"edition":3,
               	"year":2011
               },
               {
               	"title":"title2",
               	"authors":[
               	   "author2","author22"
               	],
               	"edition":2,
               	"year":2012
               }
]

对象和数组通常是JSON数据结构的最外层(不是强制规定),利用它们能创造出各种各样的数据结构。

解析与序列化

JSON数据结构可以解析为有用的javascript对象,并且相对容易实现,因此,JSON成了web服务开发中交换数据的标准。

JSON对象

JSON对象有两个方法:stringify()和parse()。

stringify()用于把javascript对象序列化为JSON字符串:

var book={
    title:"title1",
    authors:[
        "authors1"
    ],
    edition:3,
    year:2011
};

var jsonText=JSON.stringify(book); 

console.log(jsonText);
//{"title":"title1","authors":["authors1"],"edition":3,"year":2011}

默认情况下,JSON.stringify()输出的JSON字符串不包含任何空格字符或缩进。还必须注意,在序列化javascript对象时,所有函数及原型成员都会被有意忽略,不体现在结果中。此外,值为undefined的任何属性也都会被跳过。结果中最终都是值为有效JSON数据类型的实例属性。

parse()用于把JSON字符串解析为原生的javascript值:

var book={
    title:"title1",
    authors:[
       "authors1"
    ],
    edition:3,
    year:2011
};

var jsonText=JSON.stringify(book); 

var bookCopy=JSON.parse(jsonText);

console.log("title:"+bookCopy.title+";authors:"+bookCopy.authors+";edition:"+bookCopy.edition+";year:"+bookCopy.year);
//title:title1;authors:authors1;edition:3;year:2011

注意,虽然bookcopy与book具有相同的属性,当它们是两个独立的对象。没有任何关系。

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

序列化选项

JSON.stringify()除了要序列化的javascript对象外,还可以接收另外两个参数,这两个参数用于指定以不同方式序列化javascript对象。

第一个参数是个过滤器,可以是一个数组,也可以是一个函数;

第二个参数是一个选项,表示是否在JSON字符串中保留缩进。

1.过滤结果

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

var book={
    title:"title1",
    authors:[
       "authors1"
    ],
    edition:3,
    year:2011
};

var jsonText=JSON.stringify(book,["title","edition"]);

console.log(jsonText); //{"title":"title1","edition":3}

如果第二个参数是函数,那么传入的函数接收两个参数:属性名和属性值。

通过属性名可以知道如何处理要序列化的对象中的属性。属性名只能是字符串,而在值并非键值对结构的值时,键名可以是空字符串。

为了改变序列化的结果,函数返回的值就是相应的键的结果值。注意,如果函数返回了undefined,那么相应的属性会被忽略(因为JSON不支持undefined)。

        var book={
         	title:"title1",
         	authors:[
         	  "authors1","authors2"
         	],
         	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);
         //{"title":"title1","authors":"authors1,authors2","year":5000}

2.字符串缩进

JSON.stringify()的第三个参数是用于控制结果中的缩进和空白字符的。如果这个参数是一个数值,那它表示每个级别缩进的空格数(注意,最大的缩进格数为10,所有大于10的值都会自动被转换为10):

var book={
         	title:"title1",
         	authors:[
         	  "authors1","authors2"
         	],
         	edition:3,
         	year:2011
         };

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

         console.log(jsonText);
         /*
			{
			    "title": "title1",
			    "authors": [
			        "authors1",
			        "authors2"
			    ],
			    "edition": 3,
			    "year": 2011
			}
         */

如果缩进参数是一个字符串而不是数值,则这个字符串将在JSON字符串中被用作缩进字符(不再使用空格):

var book={
         	title:"title1",
         	authors:[
         	  "authors1","authors2"
         	],
         	edition:3,
         	year:2011
         };

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

         console.log(jsonText);
         /*
			{
			--"title": "title1",
			--"authors": [
			----"authors1",
			----"authors2"
			--],
			--"edition": 3,
			--"year": 2011
			}
         */

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

3.toJSON()方法

有时,如果JSON.stringify()不能满足某些对象进行自定义序列化的需求,那么可以通过对象上调用toJSON(),返回其自身的JSON数据格式。

原生的Date对象有一个toJSON()方法,能将javascript的Date对象自动换成ISO 8601日期字符串。

可为任何对象添加toJSON方法:

var book={
         	title:"title1",
         	authors:[
         	  "authors1","authors2"
         	],
         	edition:3,
         	year:2011,
         	toJSON:function(){
         		return this.title;
         	}
         };

         var jsonText=JSON.stringify(book);

         console.log(jsonText); //"title1"

把一个对象传入JSON.stringify(),序列化该对象的顺序如下:

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

解析选项

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

如果还原函数返回undefined,则表示要从结果中删除相应的键;如果返回其他值,则将该值插入结果中。如:

var book={
         	title:"title1",
         	authors:[
         	  "authors1","authors2"
         	],
         	edition:3,
         	year:2011,
         	releaseDate:new Date(2011,11,1)
         };

         var jsonText=JSON.stringify(book);

         var bookCopy=JSON.parse(jsonText,function(key,value){
         	if(key=="releaseDate"){
         		return new Date(value);
         	}else{
         		return value;
         	}
         })
         
         console.log(bookCopy.releaseDate.getFullYear()); //2011



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值