一、JSON.stringify方法的基本使用
- 作用:将对象转换成JSON字符串的格式,配合JSON.parse可实现基础版的对象深拷贝
- 语法:JSON.stringify(value[, replacer [, space]]) ```javascript let myObj1 = { name:’Tim’, age:10, friends:[1,2,3], sex:’boy’ }
// 第一个参数:必须,需要序列化的对象 let objToString1 = JSON.stringify(myObj1); console.log(objToString1); // {“name”:”Tim”,”age”:10,”friends”:[1,2,3],”sex”:”boy”}
// 第二个参数:需要对对象进行处理的函数 let objToString2 = JSON.stringify(myObj1 , function (key,value){ if (typeof value === ‘string’) return undefined; return value; }) console.log(objToString2); // {“age”:10,”friends”:[1,2,3]}
// 第三个参数:对象之间的空格数 let objToString3 = JSON.stringify(myObj1,null,’ ‘); console.log(objToString3); //{ // “name”: “Tim”, // “age”: 10, // “friends”: [ // 1, // 2, // 3 // ], // “sex”: “boy” // }
<a name="TEEwO"></a>
## 二、JSON.stringify对各种数据类型的处理
| JSON.stringify | 输入类型 | 输出 |
| --- | --- | --- |
| 基本数据类型 | string | 字符串格式 |
| | number | 字符串格式的数值 |
| | boolean | "true"/"false" |
| | null | "null" |
| | undefined / symbol | "undefined" |
| | NAN / +-Infinity | "null" |
| 引用数据类型(属性类型) | function | "undefined" |
| | Date | Date的toJSON字符串 |
| | RegExp | "{}" |
| | 数组中出现了undefined、Symbol、Function | / |
| | 普通的对象 | 1 - 如果对象有toJSON方法,则序列化toJSON方法的返回值<br />2 - 如果对象属性值为undefined,任意函数、Symbol,则忽略<br />3 - 如果以Symbol为属性键的属性都被忽略 |
<a name="AM3VB"></a>
## 三、手写JSON.stringify方法
```javascript
function jsonStringify(data){
let type = typeof data;
// 处理对基本数据类型的序列化
if (type !== 'object'){
let result = data;
if (Number.isNaN(data) || data === Infinity){
return "null";
}
if (type === "function" || type === "undefined" || type === "symbol"){
return undefined;
}
// 字符串添加双引号是为了在对象递归调用时属性值添加引号
if (type === "string"){
return `"${data}"`;
}
return data;
}else {
// 对引用类型的处理
// null 虽然是基本数据类型,但是 typeof null === ‘object’
if (data === null){
return "null";
}
// 处理 Date 的序列化
if (data.toJSON && typeof data.toJSON === 'function'){
return jsonStringify(data.toJSON())
}
// 处理RegExp的序列化
if (data instanceof RegExp){
return "{}"
}
// 处理数组的每一项,每一项的类型可能不同,在数组中,undefined,function、symbol类型序列化为null,递归调用
if (data instanceof Array){
let result = [];
data.forEach((item,index)=>{
if (typeof item === 'undefined' || typeof item === 'function' || typeof item === 'symbol') {
result[index] = "null";
} else {
result[index] = jsonStringify(item);
}
});
result = `[${result}]`;
return result.replace(/'/g,'"');
}
// 处理普通对象,对于属性值为undefined、function、symbol及属性为symbol的项直接忽略掉
let result = [];
Object.keys(data).forEach((item,index) => {
if (typeof item !== 'symbol'){
if (data[item] !== undefined && typeof data[item] !== "function" && typeof data[item] !== 'symbol' ){
result.push(`"${item}":${jsonStringify(data[item])}`)
}
}
});
return `{${result}}`.replace(/'/g,'"');
}
}
let obj2 = {
name:'myName',
age:12,
hasMarried:false,
null:null,
undefined:undefined,
hobby:undefined,
getName(){
return this.name
},
date:new Date(),
RegExp:new RegExp("a"),
array1:[1,2,undefined,function (){},45],
obj3:{
name:'hello'
}
}
// {"name":"myName","age":12,"hasMarried":false,"null":null,"date":"2021-07-21T09:41:18.270Z","RegExp":{}
,"array1":[1,2,null,null,45],"obj3":{"name":"hello"}}