JSON——《JavaScript高级程序设计》笔记
JSON (JavaScript Object Notation对象表示法)
一种结构化数据的格式,与JavaScript有相同的语法形式,但不属于JavaScript。支持多种编程语言。
1、语法
JSON有3种类型的值:简单值、对象 和 数组。
简单值:字符串、数值、布尔值、null (JSON不支持JavaScript的特殊值undefined)
对象:一组无序键值对。值可为简单值,或对象和数组。
数组:一组有序键值对。值可为简单值,或对象和数组
JSON不支持变量、函数 和 对象实例。
1-1、简单型
JSON字符串必须使用双引号(单引号会导致语法错误)
1-2、对象
JSON对象的属性必须使用双引号:
{
"name":"xiaoming",
"age":24
}
与JavaScript对象字面量的区别:无声明变量;无末尾分号。
1-3、数组
同样无声明对象;无末尾分号。
2、解析 与 序列化
2-1、JSON对象
早期JSON解析器使用JavaScript的eval()函数解析、解释 并 返回JavaScript对象和数组。ECMAScript5定义了全局对象JSON(支持IE8+ 等 主流浏览器)。
eval()对JSON数据结构求值存在风险,可能会执行恶意代码,故早期浏览器可使用shim:https://github.com/douglascrockford/JSON-js
JSON对象的两个方法:stringify()、parse()
stringify():将JavaScript对象 序列化 为JSON字符串。
var book = { title: "Professional JavaScript", authors: [ "Nicholas C. Zakas" ], edition: 3, year: 2011 }; var jsonText = JSON.stringify(book);
JSON.stringify()输出的JSON字符串 默认 不包含缩进、空格符 和 换行符。
序列化JavaScript对象时,所有函数、原型成员 和 值为undefined的属性 都会被忽略。
parse():将JSON字符串 解析 为原生JavaScript值
传给JSON.parse()的字符串不是有效JSON时,会抛出错误。
※即使stringify()之前和parse()后 两个对象属性相同,也是两个完全独立的对象。
2-2、序列化
JSON.stringify()有3个参数:JavaScript对象、过滤器、控制缩进等格式化
1-过滤器(过滤结果):数组、函数
数组过滤器:JSON.stringify()的结果 将只包含数组中列出的 属性:
var book = { title: "Professional JavaScript", authors: [ "Nicholas C. Zakas" ], edition: 3, year: 2011 }; var jsonText = JSON.stringify(book, ["title", "edition"]);
函数过滤器:函数有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}
☆实际上,第一次调用函数过滤器时,传入的是一个空字符串,值为这个book对象
2-字符串缩进
JSON.stringify()的第3个参数 用于控制结果的缩进和空白符。(换行符会在传入有效缩进参数时,自动添加)
当为数值时,表示每级缩进的空格数;
当为非数值时,做为缩进字符(不再使用空格缩进)。
※最大缩进数和缩进字符为10,超过时自动转换为10
var jsonText = JSON.stringify(book, null, "--"); 效果: { ----“title”: "Professional JavaScript", ----“authors”: [ --------"Nicholas C. Zakas" ----], ----“edition”: 3, ----“year”: 2011 }
3-toJSON()方法
toJSON()方法 可用于返回任何值;也可作为过滤器的补充,进行根精确的自定义序列化需求。
var book = { "title": "Professional JavaScript", "authors": [ "Nicholas C. Zakas" ], edition: 3, year: 2011, toJSON: function(){ return this.title; } }; var jsonText = JSON.stringify(book); alert(jsonText); 执行后将弹出消息框,内容为title属性的值: Professional JavaScript 即toJSON()方法 会在序列化之前先执行。
☆☆☆☆☆
☆ 将一个对象传入JSON.stringify()后 的序列化 顺序:
①若存在 而且 能通过toJSON()获取有效值,将先调用该方法。否则返回对象本身;
②若存在 第2参数,将①返回的值传入 过滤器;
③对②返回的每个值 进行相应的序列化;
④若存在 第3参数,对序列化后的数据 进行相应格式化。
2-3、解析
JSON.parse() 2个参数:JSON对象、函数(还原函数‘reviver’,与序列化的替换函数'replacer'具有相同签名:2个参数——键与值)
还原函数:若此函数返回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()); 执行后弹出消息框,内容为:2011 releaseDate属性保存着一个Date对象,序列化后,在bookCopy中又被还原成一个Date对象,故bookCopy.releaseDate才有一个Date对象,才可以调用getFullYear()方法。