JSON
JSON 有什么用
JSON 是一种用户数据交换的文本格式,通常用于在网站上表示和传输数据,比如服务器向客户端发送一些数据,渲染在网页上。
在历史上,XML 曾一度成为互联网存储和传输结构化数据的标准,但是其语法冗余和啰嗦,所以 JSON 出来后迅速取代 XML,目前已经成为交换数据的标准格式。
JSON 是什么
JSON 是 Javascript 的子集,是一种数据格式,利用 JavaScript 的几种模式来表示结构化的数据。
JSON 并不属于 JavaScript,只是它们拥有相同的语法,很多语言都有解析和序列化 JSON 的能力,所以 JSON 是一种通用的数据格式。
JSON 支持 3 种类型的值:简单值、对象、数组。
- 简单值包括字符串、数字、布尔、null,但是不包含 undefined。
- 对象和数组都是复杂数据类型,对象和数组内的值可以组合任意类型,包括简单值、数组、对象等。
简单值
最简单的 JSON 可以是一个数值或者一个字符串,5 或者‘‘5’’都可以是 JSON,null 和布尔值也可以是 JSON。
需要额外注意
-
字符串必须由双引号包起来。
-
undefined 会被 JSON 忽略,所以它不是 JSON 里的简单值。
对象
在 JavaScript 中,对象字面量是这样的
javascript1const person = { 2 name: 'qiuyanxi', 3 age: 29, 4}
如果用 JSON 表示则应该是这样的
json1{ 2 "name": "qiuyanxi", 3 "age": 29 4}
首先 JSON 没有变量声明,其次没有分号,此外所有属性名都必须用双引号包起来。
数组
数组的规则跟对象是一样的,没有变量,没有分号,都需要双引号包起来。以下就是一个 JSON 对象
json1["1", { "name": "qiuyanxi" }, ["2"]]
数组和对象可以自由组合,以表示更加复杂的数据结构。
JSON 怎么用
普通使用
ES5 增加了 JSON 全局对象,用来引入解析 JSON 的能力。
JSON 对象有两个方法:stringify和 parse
stringify可以把 JavaScript 序列化为 JSON 字符串,parse可以将 JSON 字符串解析为原生 JavaScript 值。
举个例子
javascript1let book={ 2 title:"Profession JavaScript", 3 edition:4, 4 year:2017 5} 6let jsonText=JSON.stringify(book) 7'{"title":"Profession JavaScript","edition":4,"year":2017}' //JSON字符串 8 9JSON.parse(jsonText) 10{title: 'Profession JavaScript', edition: 4, year: 2017}
在序列化 JavaScript 对象时,所有函数和 undefined 都会被忽略
js1let book = { title: undefined, fn: function () {} } 2JSON.stringify(book) 3;('{}')
将 JSON 字符串解析为 JavaScript 对象时,会创建一个新的对象,能够实现深拷贝。
js1let book={ 2 title:"Profession JavaScript", 3 edition:4, 4 year:2017 5} 6let jsonText=JSON.stringify(book) 7let newObj=JSON.parse(jsonText) 8 9newObj.edition=5 10newObj 11{title: 'Profession JavaScript', edition: 5, year: 2017} 12book 13{title: 'Profession JavaScript', edition: 4, year: 2017}
上面的结果就是深拷贝了一个对象,两者的属性不相交。
序列化选项
JSON.stringify除了可以接收需要序列化的对象,还可以接收两个参数,这两个参数可以指定序列化对象的方式
JSON.stringify 的第二个参数
第二个参数是过滤器,可以是数组或者函数
-
如果是数组,可以指定需要序列化的属性
下面例子中,只序列化出
js1let book = { 2 title: 'Profession JavaScript', 3 edition: 4, 4 year: 2017, 5} 6JSON.stringify(book, ['edition']) 7;('{"edition":4}') -
如果是函数,这个函数称之为还原函数(replacer),它会接收到两个参数,分别是属性名和属性值,可以根据属性名和属性值来决定序列化做的操作。
javascript1let book = { 2 title: "Profession JavaScript", 3 edition: 4, 4 year: 2017 5}; 6const jsonText = JSON.stringify(book, (key, value) => { 7 switch (key) { 8 case "title": 9 return "title is modified"; 10 case "edition": 11 return 5000; 12 case "year": 13 return undefined; 14 default: 15 return value; //一定要return value 16 } 17}); 18jsonText {"title":"title is modified","edition":5000}
第一次调用这个函数实际上会传入空字符串 key,值是 book 对象
javascript1const jsonText = JSON.stringify(book, (key, value) => { 2 console.log('key', key) 3 console.log('value', value) 4}) 5// key "" 6// value {title: "Profession JavaScript", edition: 4, year: 2017}
JSON.stringify 的第三个参数
第三个参数可以控制缩进和空格。最大缩进值为 10,大于 10 则自动设置为 10
js1const jsonText = JSON.stringify(book, null, 5); 2{ 3 "title": "Profession JavaScript", 4 "edition": 4, 5 "year": 2017 6}
js1const jsonText = JSON.stringify(book, null, 10); 2{ 3 "title": "Profession JavaScript", 4 "edition": 4, 5 "year": 2017 6}
如果设置为字符串,那么就会自动将空格转为这个字符串,字符串的最大长度限制为 10
js1const jsonText = JSON.stringify(book, null, "-"); 2{ 3-"title": "Profession JavaScript", 4-"edition": 4, 5-"year": 2017 6}
toJSON 方法
原生的 Date 对象默认带有 toJSON 方法,可以将 Date 对象转化为 ISO8601 日期字符串,本质上跟 toISOString()方法是一致的。
js1console.log(new Date().toJSON() === new Date().toISOString()) //true
我们也可以在对象中为自定义序列化添加一个 toJSON 方法,然后用 stringify 去序列化这个对象
js1let book = { 2 title: 'Profession JavaScript', 3 edition: 4, 4 year: 2017, 5 toJSON: function () { 6 return this.edition 7 }, 8} 9console.log(JSON.stringify(book)) 10// 4
在JSON.stringify 调用时,会执行以下操作:
- 如果可以获取到实际的值,则调用 toJSON 方法获取实际的值,否则使用默认的序列化
- 如果提供第二个参数,则应用过滤。传入过滤函数的值就是第 1 步返回的值
- 第 2 步返回的值会被序列化
- 如果提供了第三个参数,则相应对结果进行缩进
解析选项
JSON.parse接收第二个参数,这个参数是一个函数,称为还原函数(reviver),这个函数的参数跟 JSON.stringify一样,第一个参数为 key,第二个参数为 value。
如果这个还原函数返回 undefined,那么结果会删除相应的键。如果返回其他任何值,则会称为相应键的值插入到结果中。
js1const jsonText = JSON.stringify(book) 2 3JSON.parse(jsonText, (key, value) => { 4 switch (key) { 5 case 'edition': 6 return 5000 7 case 'title': 8 return undefined 9 case 'year': 10 return null 11 default: 12 return value 13 } 14}) 15// {edition: 5000, year: null}
总结
- JSON 是一种轻量的数据交换格式,可以很方便地表示复杂的数据结构
- JSON 格式可以表示 JavaScript 中的数字、布尔、字符串、null、数组和对象,但会忽略 undefined 和函数
- JSON 有两种方法,将 JavaScript 对象转化为 JSON 串的
JSON.stringify()方法和将 JSON 串转化为 JavaScript 值的JSON.parse()方法 - 两种方法都有额外的选项参数可以修改默认的行为,实现属性的过滤和修改。