第二十三节:JSON简介、表示方法、序列化、反序列化、深拷贝解决方案
一. Json简介
1. 说明
在目前的开发中,JSON是一种非常重要的数据格式,它并不是编程语言,而是一种可以在服务器和客户端之间传输的数据格式。
(1). JSON的全称是JavaScript Object Notation(JavaScript对象符号)
(2). JSON是由Douglas Crockford构想和设计的一种轻量级资料交换格式,算是JavaScript的一个子集;
(3). 但是虽然JSON被提出来的时候是主要应用JavaScript中,但是目前已经独立于编程语言,可以在各个编程语言中使用;
(4). 很多编程语言都实现了将JSON转成对应模型的方式;
2. 其它传输格式
(1). XML:在早期的网络传输中主要是使用XML来进行数据交换的,但是这种格式在解析、传输等各方面都弱于JSON,所以目前已经很少在被使用了;
(2). Protobuf:另外一个在网络传输中目前已经越来越多使用的传输格式是protobuf,但是直到2021年的3.x版本才支持JavaScript,所以目前在前端使用的较少;
3. Json的使用场景
(1).网络数据的传输JSON数据;
(2).项目的某些配置文件;
(3).非关系型数据库(NoSQL)将json作为存储格式;
二. Json表示方法
1 简单值
数字(Number)、字符串(String,不支持单引号)、布尔类型(Boolean)、null类型;
"ypf"
2 对象值
由key、value组成,key是字符串类型,并且必须添加双引号,值可以是简单值、对象值、数组值;
{
    "name": "ypf",
    "age": 18,
    "friend": {
      "name": "lmr"
    },
    "hobbies": ["篮球", "足球"]
  }
  
3 数组值
数组的值可以是简单值、对象值、数组值;
[
    "abc",
    123,
    {
      "name": "ypf"
    }
  ]
注意:Json中不能用单引号,不能写注释。
三. Json序列化
1. 含义
JavaScript中的复杂类型转化成JSON格式的字符串。
2. 方法
JSON.stringify() 方法
A. 直接转换,不传其它参数
B. 第二个参数replacer,可以传递一个数组表示哪些key需要序列化,也可以传入回调函数,对value进行处理
C. 第三个参数space,增加可读性, 比如传入数字代表空格,传入--代表分隔
D. 如果对象中含有toJSON方法,直接调用toJSON方法
代码分享:
{
	const obj1 = {
		name: "ypf1",
		age: 18,
		friends: {
			name: "lmr",
		},
		hobbies: ["篮球", "足球"],
	};
	const obj2 = {
		name: "ypf1",
		age: 18,
		friends: {
			name: "lmr",
		},
		hobbies: ["篮球", "足球"],
		toJSON() {
			return "hhhh";
		},
	};
	// 1.1 直接转换
	console.log("--------1.1 直接转换--------");
	const jsonString1 = JSON.stringify(obj1);
	console.log(jsonString1);
	// 1.2 第二个参数replacer
	console.log("-------1.2 第二个参数replacer--------");
	// 1.2.1 传入数组,表示哪些key需要序列化
	const jsonString2 = JSON.stringify(obj1, ["name", "age"]);
	console.log(jsonString2); //"{"name":"ypf1","age":18}"
	// 1.2.2 传入回调函数,可以对value值进行处理
	const jsonString3 = JSON.stringify(obj1, (key, value) => {
		if (key == "age") {
			return value + 10;
		}
		return value;
	});
	console.log(jsonString3);
	// 1.3 第三个参数space,增加可读性
	console.log("-- 1.3 第三个参数space,增加可读性--");
	console.log(JSON.stringify(obj1, null, 2)); //代表2个空格
	console.log(JSON.stringify(obj1, null, "---")); //代表---分隔
	// 1.4 对象中含有toJSON方法
	console.log("-- 1.4 对象中含有toJSON方法--");
	console.log(JSON.stringify(obj2)); //hhhh
}
运行结果:

四. Json反序列化
1. 含义
用来解析JSON字符串,构造由字符串描述的JavaScript值或对象
2. 方法
JSON.parse()方法
A. 直接转换,不传其它参数
B. 第二个参数receiver,可以对value进行处理
代码分享:
{
	console.log("--------2. json反序列化----------");
	const JSONString =
		'{"name":"ypf","age":18,"friends":{"name":"lmr"},"hobbies":["篮球","足球"]}';
	// 2.1 直接转换
	console.log(JSON.parse(JSONString));
	// 2.2 第二个参数receiver,可以对value进行处理
	const obj = JSON.parse(JSONString, (key, value) => {
		if (key === "age") {
			return value + 10;
		}
		return value;
	});
	console.log(obj);
}
运行结果:

五. 深拷贝解决方案
(关于引用赋值、深拷贝、浅拷贝详见:https://www.cnblogs.com/yaopengfei/p/15261698.html)
方案:
我们可以先JSON.stringify,然后JSON.parse(),实现对象的深拷贝。
缺陷:
这种方案对方法是无能为力的,是因为stringify并不会对函数进行处理,最终的对象里的方法就不见了。
代码分享:{
	console.log("--------3. 深拷贝---------");
	const obj = {
		name: "ypf1",
		age: 18,
		friends: {
			name: "lmr",
		},
		hobbies: ["篮球", "足球"],
		test() {
			console.log("test is starting");
		},
	};
	// 缺陷:创建出来的info中是没有test函数的,这是因为stringify并不会对函数进行处理;
	const jsonString = JSON.stringify(obj);
	console.log(jsonString); //字符串中没有test方法
	const info3 = JSON.parse(jsonString);
	obj.friends.name = "curry";
	console.log(info3.friends.name); //ypf1
	console.log(info3); //没有test方法
}

!
- 作 者 : Yaopengfei(姚鹏飞)
 - 博客地址 : http://www.cnblogs.com/yaopengfei/
 - 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
 - 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
                    
                
                
            
        
浙公网安备 33010602011771号