该文章只用于记录自己看掘金 弹铁蛋同学的博客个人所学到的内容,并不是很全面
1.
JSON.stringify(Symbol('x'))
JSON.stringify(undefined)
JSON.stringify(function() { return true; })
===>
undefined // undefined不是字符串
2.
const data = {
a: "a",
b: undefined,
c: Symbol("a"),
fn: function() { return true; }
};
JSON.stringify(data)
===>
'{a:"a"}'
3.
JSON.stringify(["a", undefined, Symbol("a"), function() { return true; }])
===>
'["a"]'
Symbol: Symbol是ES6新增的基础类型,用typeof或…toString检查类型的话会返回’symbol’和’[object Symbol]’,他的每一个实例都是唯一的(很像一个不能添加属性的对象),有__proto__属性
因为序列化时会忽略一些特殊的值(如#1),所以不能保证序列化后的字符串还是以特定的顺序出现(数组除外)。
如果JSON.stringify的参数如果是对象并且对象中有名为toJSON的函数,或数组的__proto__中有toJSON(数组[]中包括不行),执行的结果则是toJSON函数返回的值
JSON.stringify({
a: "a",
toJSON: function() {
return "b";
}
})
===>
'b'
var a = [1,2,3,4]
a.__proto__.toJSON = function () {}
===>
undefined
JSON.stringify会正常序列化Date的值
JSON.stringify({ a: new Date() });
===>
"{"a":"2019-12-10T06:59:58.001Z"}"
实际上Date对象自己部署了toJSON()方法,因此会被当做字符串处理
a.a.toJSON
===>
ƒ toJSON() { [native code] }
JSON.stringify(NaN)
===>
"null"
JSON.stringify(null)
===>
"null"
JSON.stringify(Infinity)
===>
"null"
JSON.stringify([new Number(1), new String("false"), new Boolean(false)]);
===>
"[1,"false",false]"
JSON.stringify(
Object.create(
null,
{
x: { value: 'json', enumerable: false },
y: { value: 'stringify', enumerable: true }
}
)
);
===>
"{"y":"stringify"}"
对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。
const obj = {
name: "loopObj"
};
const loopObj = {
obj
};
obj.loopObj = loopObj;
===>
error...
所有以symbol为属性键的属性都会被完全忽略掉,即便replacer参数中强制指定包含了它们。
JSON.stringify({ [Symbol.for("json")]: "stringify" }, function(k, v) {
if (typeof k === "symbol") {
return v;
}
})
如果不清楚JSON.stringify的第二个参数的话往下看(JSON.string的第二个参数)
JSON.string的第二个参数可以使数组,也可以是一个过滤函数
参数为数组时,相当于是前一个属性的白名单,对前边的对象进行过滤,只有对象中属性名在数组中的属性才会被执行,否则跳过
JSON.stringify({ a:1, b:2, c:3 }, ['a', 'b'])
===>
"{"a":1,"b":2}"
参数为函数时,函数有两个形参 key, value
可以使用函数来控制输出之前那些被忽略的属性
最一开始key会接收到空值,value为要序列化的对象,第一轮必须返回这个对象(value),否者JSON.string的返回值会为"""",因为下一轮执行内部需要用到之前的key,value
确保第一轮返回value的方法,最稳妥的就是在函数尾部协商return value,然后在前边做if判断拦截需要修改的数据
var a = { a:1, b:2, c:3, d: Symbol(4) }
JSON.stringify(a, function (key, value) {
console.log("key " , key)
console.log("value " , value)
if (typeof value === "symbol") {
return value.toString()
}
return value
})
===>
key // 第一个key为空
value {a: 1, b: 2, c: 3, d: Symbol(4)} // 第一个value为整个数组(value === a ===> true)
key a
value 1
key b
value 2
key c
value 3
key d
value Symbol(4)
"{"a":1,"b":2,"c":3,"d":"Symbol(4)"}" // 这个是返回值
用于在数组或者对象转换前在每个属性/索引前增加内容
参数可以使数字或字符串
对象举例:
var a = {
a: "1",
b: "2",
c: "3",
d: {
e: "4"
}
}
// 参数为字符串
JSON.stringify(a,null,'aa')
===>
"{
aa"a": "1",
aa"b": "2",
aa"c": "3",
aa"d": {
aaaa"e": "4"
aa}
}"
// 参数为数字
JSON.stringify(a,null,5)
===>
"{
"a": "1",
"b": "2",
"c": "3",
"d": {
"e": "4"
} // 每行前空5格,e空10格
}"
数组举例:
var a = [1,2,3,4,{a:1,b:2}]
// 参数为字符串
JSON.stringify(a,null,'aa')
===>
"[
aa1,
aa2,
aa3,
aa4,
aa{
aaaa"a": 1,
aaaa"b": 2
aa}
]"
// 参数为数字
JSON.stringify(a,null,5)
===>
"[
1,
2,
3,
4,
{
"a": 1,
"b": 2
}
]" // 每行前空5格,a,b空10格
参考链接 掘金 弹铁蛋同学