一、对json的理解
json是一种数据格式,不是一种编程语言,json并不从属于javascript。
json的语法可以表示以下三种类型的值
1)简单值
与js相同的语法,可以在json中表示字符串(必须使用双引号,单引号会导致语法错误)、数值、布尔值、和null,但是不支持undefined。
2)对象
json的对象是一种复杂的数据类型,表示一组无序的键值对
{ "name": "Nicholas", "age": "27" }
3)数组
表示一组有序值的列表
json的数组表示:[25,‘hi‘,true]
注:数组也没有变量和分号
4)数组和对象结合的更复杂的数组集合
[ //JSON数组也没有变量和分号 { "title":"haha", "authors":[ "1":"2", "3":"4" ] }, "name":"xixi" ]
JSON与JavaScript的对象字面量的区别:
//JavaScript对象字面量 var obj = { "name":"Nicholas", "age":29 }; //JSON对象 { "name":"Nicholas", "age":29 }
1、没有声明变量(json没有变量的概念);
2、没有末尾的分号;
3、JSON字符串必须使用双引号(单引号会导致语法错误);
二、解析与序列化
2.1 JSON对象
JSON对象有两个方法:
stringify():把js对象序列化为json字符串
parse():把json字符串解析为原生javascript值
var book = { title : "Professional JavaScript", authors : [ "Nicholas C . Zakas" ], edition : 3, year : 2011 }; var jsonText = JSON.stringify(book); alert(jsonText); // {"title":"Professional JavaScript","authors":["Nicholas C . Zakas"],"edition":3,"year":2011}
默认的JSON.stringify()输出的JSON对象不包含任何空格字符或缩减。
在序列化JavaScript对象时,所有的函数及原型对象都会被有意忽略,不体现在结果中。此外,值为undefined的任何属性也都会被跳过,结果中最终都是值为有效JSON数据类型的实例属性。
var bookcopy = JSON.parse(jsonText); //Object {title: "Professional JavaScript", authors: Array[1], edition: 3, year: 2011}
2.2 序列化选项
JSON.stringify()可以接收三个参数,第一个参数是要序列化的javascript对象,第二个参数是一个过滤器,可以是一个数组也可以是一个函数;第三个参数是一个选项,表示是否在JSON字符串中保留缩进。
当第二个参数是数组的时候,返回的结果只会包含数组里的属性;
var jsonText = JSON.stringify(book, ["title","edition"]); //{"title":"Professional JavaScript","edition":3}
当是函数的时候,函数有两个参数,属性名和属性值,根据属性名可以知道应该序列化哪些属性,函数返回值就是相应键的值,如果函数返回undefined,则相应属性忽略。
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":"Professional JavaScript","authors":"Nicholas C . Zakas","year":5000}
第三个参数用与控制结果中的缩进与空白,参数是数值,表示每个级别缩进的空格数,最大缩进格数为10;参数也可以是一个字符串,如制表符或"- -",字符串长不能超过10;
toJSON()方法:作为函数过滤器的补充,返回其自身的json数据格式。
var book = { title : "Professional JavaScript", authors : [ "Nicholas C . Zakas" ], edition : 3, year : 2011, toJSON: function(){ return this.title; } }; var jsonText = JSON.stringify(book); //"Professional JavaScript"
假设把一个对象传入JSON.stringify(),序列化该对象的顺序如下:
(1)如果存在toJSON()方法而且能通过它取得有效的值,则调用该函数。否则,返回对象本身。
(2)如果提供了第二个参数,应用这个函数过滤器。传入函数过滤器的值是第(1)步返回的值。
(3)对第(2)步返回的每个值进行相应的序列化。
(4)如果提供了第三个参数,执行相应的格式化。
2.3 解析选项
JSON.parse()也可以接收一个参数,参数是一个函数,称为还原函数(reviver),再将日期字符串转换成Date对象时,经常要用到还原函数。
var book = { title : "Professional JavaScript", authors : [ "Nicholas C . Zakas" ], edition : 3, year : 2011, releaseDate : new Date(2011, 11,1) }; var jsonText = JSON.stringify(book); //{"title":"Professional JavaScript","authors":["Nicholas C . Zakas"],"edition":3,"year":2011,"releaseDate":"2011-11-30T16:00:00.000Z"}
var bookcopy = JSON.parse(jsonText, function(key, value){ if(key == "releaseDate"){ return new Date(value); } else { return value; } }); //Object {title: "Professional JavaScript", authors: Array[1], edition: 3, year: 2011, releaseDate: Thu Dec 01 2011 00:00:00 GMT+0800 (中国标准时间)} alert(bookcopy.releaseDate.getFullYear()); //2011
三、再说几句toJSON()
toJSON 方法由 JSON.stringify 函数使用。 JSON.stringify 将 JavaScript 值序列化为 JSON 文本。 如果向 JSON.stringify 提供了 toJSON 方法,则在调用 JSON.stringify 时将调用 toJSON 方法。
toJSON 方法是 Date JavaScript 对象的内置成员。 它返回 UTC 时区的 ISO 格式日期字符串(由后缀 Z 表示)。
可重写 Date 类型的 toJSON 方法,也可为其他对象类型定义 toJSON 方法,以实现在 JSON 序列化之前对特定对象类型进行数据转换。
var contact = new Object(); contact.firstname = "Jesper"; contact.surname = "Aaberg"; contact.phone = ["555-0100", "555-0120"]; contact.toJSON = function(key) { var replacement = new Object(); for (var val in this) { if (typeof (this[val]) === ‘string‘) replacement[val] = this[val].toUpperCase(); else replacement[val] = this[val] } return replacement; }; var jsonText = JSON.stringify(contact);//{"firstname":"JESPER","surname":"AABERG","phone":["555-0100","555-0120"]}