//JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串。
// ## 语法
// JSON.stringify(value[, replacer[, space]])
// - value:
// 必需, 要转换的 JavaScript 值(通常为对象或数组)。
// - replacer:
// 可选。用于转换结果的函数或数组。
// 如果 replacer 为函数,则 JSON.stringify 将调用该函数,并传入每个成员的键和值。使用返回值而不是原始值。如果此函数返回 undefined,则排除成员。根对象的键是一个空字符串:""。
// 如果 replacer 是一个数组,则仅转换该数组中具有键值的成员。成员的转换顺序与键在数组中的顺序一样。
// - space:
// 可选,文本添加缩进、空格和换行符,如果 space 是一个数字,则返回值文本在每个级别缩进指定数目的空格,如果 space 大于 10,则文本缩进 10 个空格。space 也可以使用非数字,如:\t。
// 常用JSON.stringify()有那些=>数据的深拷贝
let obj = {
a: '你好',
b: '你好b',
c: '防守打法c'
}
let obj1 = JSON.parse(JSON.stringify(obj))
obj1.a = "你好a"
console.log(obj) // {a: "你好", b: "你好b", c: "防守打法c"}
console.log(obj1) // {a: "你好a", b: "你好b", c: "防守打法c"}
console.log(JSON.stringify(obj)) // {"a":"你好","b":"你好b","c":"防守打法c"}
// ### 返回值
// 对于undefined、任意的函数,symbol作为对象属性值的时候,JSON.stringify() 将跳过(忽略)对他们进行序列化
// 对于undefined、任意的函数以及 symbol 作为数组元素值时,JSON.stringify() 将会将它们序列化为 null
// 对于undefined、任意的函数以及 symbol 被 JSON.stringify() 作为单独的值进行序列化时,都会返回 undefined
const data = {
a: "aaa",
b: undefined,
c: Symbol("dd"),
fn: function() {
return true;
}
};
console.log(JSON.stringify(data)); // {"a":"aaa"}
console.log(JSON.parse(JSON.stringify(data)))
// 延伸问题:
// 对象里的属性值存在undefined如何去掉拥有undefined属性值的属性?
// ### 非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中
const data = {
a: "aaa",
b: undefined,
c: Symbol("dd"),
fn: function() {
return true;
},
d: "ddd"
};
JSON.stringify(data); // 输出:?
// "{"a":"aaa","d":"ddd"}"
JSON.stringify(["aaa", undefined, function aa() {
return true
}, Symbol('dd'),"eee"]) // 输出:?
// "["aaa",null,null,null,"eee"]"
// JSON.stringify() 序列化时会忽略一些特殊的值,所以不能保证序列化后的字符串还是以特定的顺序出现(数组除外)。
// ### 转换值如果有 toJSON() 函数,该函数返回什么值,序列化结果就是什么值,并且忽略其他属性的值。
JSON.stringify({
say: "hello JSON.stringify",
toJSON: function() {
return "today i learn";
}
})
// "today i learn"
// ### JSON.stringify() 将会正常序列化 Date 的值
JSON.stringify({ now: new Date() });
// "{"now":"2019-12-08T07:42:11.973Z"}"
// 实际上 Date 对象自己部署了 toJSON() 方法(同Date.toISOString()),因此 Date 对象会被当做字符串处理。
// ### NaN 和 Infinity 格式的数值及 null 都会被当做 null。
JSON.stringify(NaN)
// "null"
JSON.stringify(null)
// "null"
JSON.stringify(Infinity)
// "null"
// ### 循环引用报错
// 对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。
const obj = {
name: "loopObj"
};
const loopObj = {
obj
};
// 对象之间形成循环引用,形成闭环
obj.loopObj = loopObj;
// 封装一个深拷贝的函数
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
}
// 执行深拷贝,抛出错误
deepClone(obj)
/**
VM44:9 Uncaught TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
| property 'loopObj' -> object with constructor 'Object'
--- property 'obj' closes the circle
at JSON.stringify (<anonymous>)
at deepClone (<anonymous>:9:26)
at <anonymous>:11:13
*/