重新认识JSON

424 阅读4分钟

早之前,接触JSON一般是在ajax传递数据的时候。
JSON凭借着简单,轻量,易于交换数据的特点,被广泛使用
但感觉之前对JSON的认识是很浅显的,只知道这是个类似于js对象的数据格式,还有一些JSON的相关函数
所以今天想去重新梳理一下JSON的相关知识,希望对JSON会有全新的认识.

1.JSON是一个轻量级,广泛用于数据交换的数据格式
为什么这么说,我们先理解一些相关概念
(1)数据格式
简单来说,数据格式就是我们用来描述的数据的一种规范,一种方法.
比如说,对于 一件衣服 可以有价格$65,颜色红色,尺寸s码,那么描述它的话,可以
price="$65"&color="red"&size="s";===urlencoded
{price:"$65",color:"red",size:"s"};====JSON
<price>$65</price><color>red</color><size>s</size>; ====XML
(2)轻量级
JSON之所以被称为轻量级,是因为它在传递时使用的是键值对的方式,相对于xml格式,
脱离了需要使用标签的累赘,所以在相同的传递大小相同的数据时,JSON所需要的带宽更小,
也就是说它更加的轻量,在大数据量的传输时优势明显.
(3)广泛使用
除了轻量这个优势之外,JSON易于人和机器去理解(基于文本),
也就是说易于机器去阅读,解析和编写,所以JSON会被广泛用于数据交换.


2. JSON与js对象之间的关系
许多人会觉得JSON只不过是js对象的子集,
因为js对象不强制要求对象的属性带双引号,但是JSON有强制要求.
但事实上并非如此,JSON全称为JavaScript object notation,
所以我认为JSON是基于js对象表现形式的数据格式,也就是是其格式与js对象相似.

对比内容 JSON JS对象
键名 必须是加双引号 可允许不加、加单引号、加双引号
逗号问题 最后一个属性后面不能有逗号 可以
数值 前导0不能用,小数点后必须有数字 没限制

3. JSON相关函数

JSON.parse()

parse函数是用来解析JSON数据的,将JSON字符串转化为JavaScript值或者对象。

```
const jsonStr = '"json"'
const jsonObj = '{"a":1}'
JSON.parse(jsonStr) //  字符串"json"
JSON.parse(jsonObj) // 对象 {a:1}
```  

也可以传入一个可选的函数(reviver)对转化得到的对象进行操作,也就是真正的返回值是在得到parse解析后会调用该函数处理再返回。

const jsonObj = '{"a":1}'
JSON.parse(jsonObj,function(k,v){
console.log(k,v); // a 1 
                  // '' {"a":1}
return v
})

reviver会依次处理对象属性及属性包含的属性,这意味着reviver处理是深层次的,会遍历对象中所有属性,包括属性如果是对象,也会一样被处理(处理时最里层属性优先)。

const jsonObj = '{"a":{"b":1}}';
JSON.parse(jsonObj, function(k, v) {
console.log(k, v); //b 1 最里层属性优先处理
                    //a { b: 1 }
                    //'' { a: { b: 1 } }  //处理后的解析值
return v;
});

reviver会将属性和属性值作为参数传入,如果reviver没有返回值(或者返回值是undefined)则会将对象从所属对象中删除,返回其他值就替换原属性值。

const jsonObj = '{"a":{"b":1}}';
JSON.parse(jsonObj, function(k, v) {
console.log(k, v); //b 1 最里层属性优先处理
                   //a { b: 1 }
                   //'' { }  //处理后的解析值为空数组,因为reviver没有返回值
});

当对象遍历完所有属性,会最后遍历parse的解析对象,此时 传入的k(属性)为"",传入的v(属性值)为修改后的解析值。

const jsonObj = '{"a":{"b":1}}';
JSON.parse(jsonObj, function(k, v) {
console.log(k, v); //b 1 最里层属性优先处理
                       //a { b: 1 }
                       //'' { a: { b: 1 } }  //处理后的解析值
return v;
});

如果parse解析后是基本类型值(string,number,boolean),则reviver不会处理。

JSON.stringify()

将JavaScript值转化为转化为JSON字符串,可以传入replacer函数 和 空格数(space)

const obj  = {a:1,b:2}
const jsonobj = JSON.stringify(obj)
console.log(jsonobj);  // '{"a":1,"b":2}'

replacer如果是函数对序列化之后的每一个属性进行转化和处理(与parse方法的reviver相似)。
replacer如果是数组的话,只有包含在该数组中的属性才会被保留
如果不传又或者为null,将不做处理

const obj  = {a:1,b:2}
const jsonobj = JSON.stringify(obj,['a'])
const jsonobj1 = JSON.stringify(obj,function(k,v){
console.log(k); // a,b
return v
})

console.log(jsonobj); // '{"a":1}'
console.log(jsonobj1); //'{"a":1,"b":2}'

空格数space用以json数据的空格设置,美化输出
注意:
空格数最多为10,且不能小于1,否则被当做没有空格
如果传入为字符串,会截取前10个字符串,并被当做空格

const obj  = {a:1,b:2}
const jsonobj = JSON.stringify(obj,function(k,v){
return v
},5)

console.log(jsonobj);  // '{
                                "a": 1,
                                "b": 2
                           }'