按照 JSON 的规范,使用 JSON.stringify() 做对象序列化时,如果一个属性为函数,那这个属性就会被忽略。
const data1 = {
a: 'aaa',
fn: function() {
return true
}
}
JSON.stringify(data)
// 结果是 "{"a":"aaa"}"
还有一种情况,一个属性的值为 undefined
const data2 = {
a: 'abc',
b: undefined
}
JSON.stringify(data2)
// 结果是 "{"a":"abc"}"
如果属性为 null
则可以正常序列化这个属性:
const data3 = {
a: 'abc',
b: null
}
JSON.stringify(data3)
// 结果是 "{"a":"abc","b":null}"
因为 null
可表示已经赋值,而 undefined
表示未定义、未赋值,所以执行 JSON.stringify
不会处理。
stringify
函数
stringify
函数的定义为 JSON.stringify(value [, replacer [, space]])
后面还带有我不常用两个可选参数 replacer 和 space
value
参数不多解释,replacer
其实就是一个自定义函数,可以改变 JSON.stringify
的行为,space
就是格式化输出,最大值为 10,非整数时取值为 1
stringify
输出 Function
本质上无论怎么改,stringify
还是不会输出 Function
,但是 Function
可以调用 toString()
方法的,所以思路就很明了了。
const data1 = {
a: 'aaa',
fn: function() {
return true
}
}
const replace = function(k ,v) {
if(typeof v === 'function') {
return Function.prototype.toString.call(v)
}
return v
}
JSON.stringify(data1, replace)
// 结果 "{"a":"aaa","fn":"function () {\n return true\n }"}"
同理可证 undefined
也能输出了
const replace = function(k ,v) {
if(v === undefined){
return 'undefined'
}
return v
}
stringify
格式化输出
JSON.stringify
的第三个参数很简单,相当于我们编辑器的 tab_size
const data4 = {
a: 'abc',
b: null,
c: {
x: 'xxx',
y: 'yyy',
z: 2046
},
d: 9527
}
JSON.stringify(data4, null, 2);
// 输出结果
/*
"{
"a": "abc",
"b": null,
"c": {
"x": "xxx",
"y": "yyy",
"z": 2046
},
"d": 9527
}"
*/
toJSON
方法
toJSON
是个覆盖函数,尽量少用,看了代码就懂了:
const data5 = {
a: 'abc',
b: null,
c: {
x: 'xxx',
y: 'yyy',
z: 2046
},
d: 9527,
toJSON: function() {
return 'WTF'
}
}
JSON.stringify(data5, null, 2);
// 结果返回 "WTF"