JSON定义:JSON 不支持变量、函数或对象实例,它就是一种表示结构化数据的格式。
JSON表示范围:JSON能表示对象、数组、字符串、数字、布尔、null类型,类型为undefined的值在解析时会被跳过。
JSON的序列化:将JS对象转换为JSON字符串。
早期采用eval()函数序列化JSON对象,但是eval存在风险可能会被注入恶意代码,替代方案:shim:https://github.com/douglascrockford/JSON-js。
ECMAScript 5定义了全局的JSON对象用于json的处理,JSON 对象有两个方法:stringify()和 parse(),这两个方法分别用于把 JavaScript 对象序列化为 JSON 字符串和把 JSON 字符串解析为原生 JavaScript 值。
stringify():
1、默认情况下,JSON.stringify()输出的JSON字符串不包含任何空格字符或缩进
2、在序列化 JavaScript 对象时,所有函数及原型成员都会被有意忽略,不体现在结果中。此外,值为 undefined 的任何属性也都会被跳过。
3、JSON.stringify()除了要序列化的 JavaScript 对象外,还可以接收另外两个参数,这两 个参数用于指定以不同的方式序列化 JavaScript 对象。第一个参数是个过滤器,可以是一个数组,也可 以是一个函数;第二个参数是一个选项,表示是否在 JSON 字符串中保留缩进。
第一个参数传入数组表示返回的结果字符串中,就只会包含这两个属性
var book = {
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
edition: 3,
year: 2011
};
var jsonText = JSON.stringify(book, ["title", "edition"]);
{"title":"Professional JavaScript","edition":3}
第一个参数传入函数可以自定义序列化结果,如果函数返回了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;
}
});
{"title":"Professional JavaScript","authors":"Nicholas C. Zakas","year":5000}
第二个参数控制结果中的缩进和空白符:如果这个参数是一个数 值,那它表示的是每个级别缩进的空格数。最大缩进空 格数为 10,所有大于 10 的值都会自动转换为 10
var book = {
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
edition: 3,
year: 2011
};
var jsonText = JSON.stringify(book, null, 4);
{
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
"edition": 3,
"year": 2011
}
如果缩进参数是一个字符串而非数值,则这个字符串将在 JSON 字符串中被用作缩进字符
var jsonText = JSON.stringify(book, null, " - -");
{
--"title": "Professional JavaScript",
--"authors": [
----"Nicholas C. Zakas"
--],
--"edition": 3,
--"year": 2011
}
JSON.stringify()还是不能满足对某些对象进行自定义序列化的需求。在这些情况下, 可以给对象定义 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);
toJSON()可以作为函数过滤器的补充,因此理解序列化的内部顺序十分重要。假设把一个对象传 入 JSON.stringify(),序列化该对象的顺序如下。
(1) 如果存在 toJSON()方法而且能通过它取得有效的值,则调用该方法。否则,返回对象本身。
(2) 如果提供了第二个参数,应用这个函数过滤器。传入函数过滤器的值是第(1)步返回的值。
(3) 对第(2)步返回的每个值进行相应的序列化。
(4) 如果提供了第三个参数,执行相应的格式化。 无论是考虑定义 toJSON()方法,还是考虑使用函数过滤器,亦或需要同时使用两者,理解这个顺 序都是至关重要的。
JSON.parse():
将JSON转成js对象,可以接收另一个参数,该参数是一个函数,将在每个键值对儿上调用。被称为还原函数(reviver), 接收两个参数,一个键和一个值,而且都需要返回一 个值如果还原函数返回 undefined,则表示要从结果中删除相应的键;如果返回其他值,则将该值插 入到结果中
var book = {
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
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;
} });
alert(bookCopy.releaseDate.getFullYear());