工具函数JSON.stringify()将JSON对象序列化为字符串时也用到了ToString.
看下面的代码:
console.log(JSON.stringify(42));
console.log(JSON.stringify("42"));
console.log(JSON.stringify(null));
console.log(JSON.stringify(true));
所有安全的JSON值都可以使用JSON.stringify字符串化.
安全的JSON值: 能够呈现为有效JSON格式的值
不安全的JSON值:
// undefined、function、symbol
// 遇到以上类型时会自动忽略(undefined)
console.log(JSON.stringify(undefined));
console.log(JSON.stringify(function(){}));console.log(JSON.stringify([1, undefined, function(){},4]));
console.log(JSON.stringify({a:2, b:function(){}}));
如果对象中定义了toJSON方法,JSON字符串化时会首先调用该方法,然后用它的返回值来进行序列化.
// 未定义toJSON,一个循环引用
var o ={};
var a = {b: 42,c: o,d: function(){}
};
o.e = a;
JSON.stringify(a);
// 自定义toJSON,返回一个安全的JSON值
var o = {};
var a = {b: 42,c: o,d: function(){}
};
a.toJSON = function(){return { b: this.b};
};
console.log(JSON.stringify(a));
可以使用toJSON方法来返回一个相对安全的值.
// toJSON()应该"返回一个能够呗字符串化的安全的JSON值",而不是"返回一个JSON字符串"
var a ={val: [1,2,3],toJSON: function() {return this.val.slice(1)}
};
var b = {val:[1,2,3],toJSON: function() {return "[" + this.val.slice(1).join() + "]";}
};
console.log(JSON.stringify(a));
console.log(JSON.stringify(b));
// 可以看出第二个函数,是对toJSON返回的字符串做字符串化,而非数组本身.
我们还可以向JSON.stringify()传递一个可选参数replacer用来指定对象序列化过程中哪些属性应该被处理
// replacer参数
var a = {b: 42,c: "42",d: [1,2,3]
};
console.log(JSON.stringify(a, ["b", "c"])); // 需要key为b 或 c的
console.log(JSON.stringify(a, function(k,v){if(k !== "c") return v;
}));
space(可选参数)
// JSON.stringify还有一个可选参数space,用来指定输出的缩进格式
var a ={b: 42,c: "42",d: [1,2,3]
};
console.log(JSON.stringify(a, null, 1));
console.log(JSON.stringify(a, null, 3));
console.log(JSON.stringify(a, null, '--'));
参考《你不知道的JavaScript》(中卷)P48~P52