第20章 JSON
1.JSON是一个轻量级的数据格式,可以简化表示复杂数据结构的工作量,可以将JSON 数据结构解析为有用的 JavaScript 对象。
2.JSON 的语法可以表示以下三种类型的值:
- 简单值:字符串(必须使用双引号)、数值、布尔值和 null。但不支持undefined。
- 对象:一组无序的键值对儿。每个键值对儿中的值可以是简单值,也可以是复杂数据类型的值。(没有声明变量和末尾的分号,对象的属性必须加引号)
- 数组:一组有序的值的列表,可以通过数值索引来访问其中的值。数组的值可以是任意类型——简单值、对象或数组。(也没有变量和分号)
JSON 不支持变量、函数或对象实例,对象和数组通常是 JSON 数据结构的最外层形式。
3.JSON对象的stringify()方法:把 JavaScript 对象序列化为 JSON 字符串,接收3个参数,第一个参数是要序列化的对象,第二个参数是过滤器(可以是一个数组或者函数,可选),第三个参数是一个选项用于控制结果中的缩进和空白符(如果是一个数值,那它表示每个级别缩进的空格数,最大缩进空格数为10,大于 10 的值都会自动转换为 10;如果一个字符串,则这个字符串将在 JSON 字符串中被用作缩进字符)
在序列化 JavaScript 对象时,所有函数及原型成员都会被有意忽略,不体现在结果中。此外,值为 undefined 的任何属性也都会被跳过。结果中最终都是值为有效 JSON 数据类型的实例属性。
1⃣️如果过滤器参数是数组,那么 JSON.stringify()的结果中将只包含数组中列出的属性。
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}
2⃣️如果过滤器参数是函数,函数接收两个参数,属性(键)名和属性值。根据属性(键)名可以知道应该如何处理要序列化的对象中的属性。
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}
4.给对象定义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);
5.假设把一个对象传 入 JSON.stringify(),序列化该对象的顺序如下:
- (1) 如果存在 toJSON()方法而且能通过它取得有效的值,则调用该方法。否则,返回对象本身。
- (2) 如果提供了第二个参数,应用这个函数过滤器。传入函数过滤器的值是第(1)步返回的值。
- (3) 对第(2)步返回的每个值进行相应的序列化。
- (4) 如果提供了第三个参数,执行相应的格式化。
6.JSON对象的parse()方法:把 JSON 字符串解析为原生 JavaScript 值,接收两个参数,第一个参数是要解析的JSON字符串,第二个参数是一个还原函数,接收两个参数,一个键和一个值(如果还原函数返回 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());
以上代码先是为 book 对象新增了一个 releaseDate 属性,该属性保存着一个 Date 对象。这个 对象在经过序列化之后变成了有效的 JSON 字符串,然后经过解析又在 bookCopy 中还原为一个 Date 对象。还原函数在遇到"releaseDate"键时,会基于相应的值创建一个新的 Date 对象。结果就是 bookCopy.releaseDate 属性中会保存一个 Date 对象。正因为如此,才能基于这个对象调用 getFullYear()方法。