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 中,对象字面量是这样的
const person={name:"qiuyanxi",age:29};
如果用 JSON 表示则应该是这样的
{"name":"qiuyanxi","age":29}
首先 JSON 没有变量声明,其次没有分号,此外所有属性名都必须用双引号包起来。
数组
数组的规则跟对象是一样的,没有变量,没有分号,都需要双引号包起来。以下就是一个 JSON 对象
["1",{"name":"qiuyanxi"},["2"]]
数组和对象可以自由组合,以表示更加复杂的数据结构。
JSON 怎么用
普通使用
ES5增加了 JSON 全局对象,用来引入解析 JSON 的能力。
JSON 对象有两个方法:stringify和 parse
stringify可以把 JavaScript 序列化为 JSON 字符串,parse可以将 JSON 字符串解析为原生 JavaScript 值。
举个例子
let book={title:"Profession JavaScript",edition:4,year:2017}let jsonText=JSON.stringify(book)'{"title":"Profession JavaScript","edition":4,"year":2017}' //JSON字符串JSON.parse(jsonText){title: 'Profession JavaScript', edition: 4, year: 2017}
在序列化 JavaScript 对象时,所有函数和 undefined 都会被忽略
let book={title:undefined,fn:function (){}}JSON.stringify(book)'{}'
将JSON字符串解析为JavaScript 对象时,会创建一个新的对象,能够实现深拷贝。
let book={title:"Profession JavaScript",edition:4,year:2017}let jsonText=JSON.stringify(book)let newObj=JSON.parse(jsonText)newObj.edition=5newObj{title: 'Profession JavaScript', edition: 5, year: 2017}book{title: 'Profession JavaScript', edition: 4, year: 2017}
上面的结果就是深拷贝了一个对象,两者的属性不相交。
序列化选项
JSON.stringify除了可以接收需要序列化的对象,还可以接收两个参数,这两个参数可以指定序列化对象的方式
JSON.stringify的第二个参数
第二个参数是过滤器,可以是数组或者函数
如果是数组,可以指定需要序列化的属性
下面例子中,只序列化出
let book={title:"Profession JavaScript",edition:4,year:2017}JSON.stringify(book,['edition'])'{"edition":4}'
如果是函数,这个函数称之为还原函数(replacer),它会接收到两个参数,分别是属性名和属性值,可以根据属性名和属性值来决定序列化做的操作。
let book = {title: "Profession JavaScript",edition: 4,year: 2017};const jsonText = JSON.stringify(book, (key, value) => {switch (key) {case "title":return "title is modified";case "edition":return 5000;case "year":return undefined;default:return value; //一定要return value}});jsonText {"title":"title is modified","edition":5000}
第一次调用这个函数实际上会传入空字符串 key,值是 book 对象
const jsonText = JSON.stringify(book, (key, value) => {console.log("key", key);console.log("value", value);});// key ""// value {title: "Profession JavaScript", edition: 4, year: 2017}
JSON.stringify的第三个参数
第三个参数可以控制缩进和空格。最大缩进值为10,大于10则自动设置为10
const jsonText = JSON.stringify(book, null, 5);{"title": "Profession JavaScript","edition": 4,"year": 2017}
const jsonText = JSON.stringify(book, null, 10);{"title": "Profession JavaScript","edition": 4,"year": 2017}
如果设置为字符串,那么就会自动将空格转为这个字符串,字符串的最大长度限制为10
const jsonText = JSON.stringify(book, null, "-");{-"title": "Profession JavaScript",-"edition": 4,-"year": 2017}
toJSON 方法
原生的 Date 对象默认带有 toJSON 方法,可以将 Date 对象转化为 ISO8601日期字符串,本质上跟 toISOString()方法是一致的。
console.log(new Date().toJSON() === new Date().toISOString());//true
我们也可以在对象中为自定义序列化添加一个 toJSON 方法,然后用 stringify 去序列化这个对象
let book = {title: "Profession JavaScript",edition: 4,year: 2017,toJSON: function () {return this.edition;}};console.log(JSON.stringify(book));// 4
在JSON.stringify 调用时,会执行以下操作:
- 如果可以获取到实际的值,则调用 toJSON 方法获取实际的值,否则使用默认的序列化
- 如果提供第二个参数,则应用过滤。传入过滤函数的值就是第1步返回的值
- 第2步返回的值会被序列化
- 如果提供了第三个参数,则相应对结果进行缩进
解析选项
JSON.parse接收第二个参数,这个参数是一个函数,称为还原函数(reviver),这个函数的参数跟 JSON.stringify一样,第一个参数为 key,第二个参数为 value。
如果这个还原函数返回 undefined,那么结果会删除相应的键。如果返回其他任何值,则会称为相应键的值插入到结果中。
const jsonText = JSON.stringify(book);JSON.parse(jsonText, (key, value) => {switch (key) {case "edition":return 5000;case "title":return undefined;case "year":return null;default:return value;}});// {edition: 5000, year: null}
总结
- JSON 是一种轻量的数据交换格式,可以很方便地表示复杂的数据结构
- JSON 格式可以表示 JavaScript 中的数字、布尔、字符串、null、数组和对象,但会忽略 undefined 和函数
- JSON 有两种方法,将JavaScript 对象转化为 JSON 串的
JSON.stringify()方法和将 JSON 串转化为 JavaScript 值的JSON.parse()方法 - 两种方法都有额外的选项参数可以修改默认的行为,实现属性的过滤和修改。
