Skip to content

JSON

一种数据格式,本质是对象;它不属于 JavaScript,只是拥有相同的语法

语法

JSON 支持三种类型的值:

​ 简单值:字符串、数值、布尔值和 null;但是 undefined 不行

​ 对象:键值对组成的数据类型

​ 数组

JSON 没有变量、函数、对象实例的概念;JSON 的所有标记都只是为了表示结构化数据,虽然它借用了 JavaScript 的语法,但是二者本质上有区别

简单值

最简单的 JSON 可以是一个数值,例如:5;还可以是一个字符串,例如:"hello"

JavaScript 字符串与 JSON 字符串的主要区别是,JSON 字符串必须使用双引号

对象

JSON 对象的属性名需要用双引号包围起来;JSON 同一个对象中不允许出现两个相同的值

数组

数组和对象可以混合使用

解析与序列化

JSON 的流行不仅仅是因为其语法与 js 类似,很大程度是因为 JSON 可以直接被解析为可用的 js 对象

JSON 对象

早期的 JSON 解析器基本上就相当于 JavaScript 的 eval()函数;因为 JSON 是 js 语法的子集,所以 eval()可以解析、解释,并将其作为 js 对象和数组返回;ECMAScript 5 增加了 JSON 全局对象,正式引入解析 JSON 的能力

JSON 对象有两种方法:stringify()和 parse(),前者将 js 序列化为 JSON 字符串,以及将 JSON 解析为原生 js 值

stringify()将 js 对象序列化为 JSON 字符串;一般情况下这个 JSON 字符串中不包含空格或回车

序列化 js 对象时,所有的函数和原型成员都会有意地在结果中省略,值为 undefined 的任何属性也会被跳过,最后得到的 JSON 数据类型是所有实例属性均为有效的

通过 JSON 字符串解析为 js 的对象,将会是一个新对象

序列化选项

stringify()方法还可以接收两个参数:过滤器(数据或函数)、缩进选项(用于缩进结果字符串)

1、过滤结果

如果过滤器是数组,则返回的结果只会包含该数组中列出的对象属性

如果过滤器是函数,则提供的函数接收两个参数:属性名(key)、属性值(value),属性值是字符串,只是在值不属于某个键值对时会是空字符串;该函数的返回值应该是 key 对应的 value,如果返回 undefined 则该属性会被忽略

函数过滤器会应用到要序列化的对象所包含的所有对象

2、字符串缩进

控制参数是数值时,表示每一级缩进的空格数(最大值为 10)

当传入缩进参数时,stringify 方法会自动插入换行符,以便更好地查看

如果缩进参数是字符串,则 JSON 字符串将会使用该符号来缩进,而不是空格(也可以使用字符串将 Tab 设置为缩进方案,同样的字符串最长长度也是 10)

3、toJSON()方法

可以通过在对象上定义 toJSON()方法来自定义 JSON 序列化方式,该对象调用 stringify()时会使用定义的方法

该方法可以返回任意序列化值,都可以起到相应作用;如果对象被嵌入到另一个对象中,返回 undefined 会导致值变成 null;如果是顶级对象,则本身就是 undefined

箭头函数不能用于定义 toJSON()方法;因为箭头函数的词法作用域是全局作用域,这种情况不合适

可以在 toJSON()方法中过滤相关内容,stringify()方法执行步骤为:

​ 1、如果可以获取实际值,则调用 toJSON()方法获取实际值,否则使用默认方法序列化

​ 2、如果提供了第二个参数,则应用过滤;传入过滤函数的值就是第一步返回的值

​ 3、第二步每个返回的值都会相应的进行序列化

​ 4、如果提供了第三个参数,则应用缩进

解析选项

parse()方法也可以接受另一个函数参数,会针对每个键值对都调用一次

这个函数被称为还原函数;和 stringify 方法起过滤作用的代替函数接收的参数一样:key、value,也需要返回值

如果返回 undefined,则结果就会删除相应的键;返回其他值就会成为相应的键值插入到结果中