JSON.stringify()
函数是一种将JavaScript对象转化成JSON的权威的方式。很多JavaScript框架在内部使用JSON.stringify()
:Express的res.json()
,Axios的post()
和Webpack的统计数据都是调用的JSON.stringify()
。在这篇文章中,我将提供一个JSON.stringify()
的实践总结,包括异常情况。
入门
所有的现代JavaScript运行时都支持JSON.stringify
。甚至Internet Explorer已经从IE8开始支持JSON.stringify()
。接下来是一个将一个简单的对象转化成JSON的例子:
const obj = { answer: 42 };
const str = JSON.stringify(obj);
str; // '{"answer":42}'
typeof str; // 'string'
在下面展示的例子中,你可以JSON.stringify()
和JSON.parse()
一起使用。这种模式是JavaScript对象深拷贝的一种方式。
const obj = { answer: 42 };
const clone = JSON.parse(JSON.stringify(obj));
clone.answer; // 42
clone === obj; // false
错误和边缘事例
JSON.stringify()
会在它发现一个循环对象的时候抛出一个错误。换句话说,如果一个对象obj
有一个属性,这个属性的值是obj
,JSON.stringify()
将抛出一个错误。
const obj = {};
// 循环对象引用自身
obj.prop = obj;
// 抛出 "TypeError: TypeError: Converting circular structure to JSON"
JSON.stringify(obj);
这是JSON.stringify()
抛出异常的唯一一个情况,除非你在使用自定义的toJSON
函数或替代函数。然而,你仍然应该将JSON.stringify()
调用包裹在try/catch
中,因为循环对象确定会在实践中冷不丁地出现。
有一些边缘事例中,JSON.stringify()
没有抛出错误,但是你可能想要它抛出错误。比如,JSON.stringify()
将NaN
和Infinity
转化成null
:
const obj = { nan: parseInt('not a number'), inf: Number.POSITIVE_INFINITY };
JSON.stringify(obj); // '{"nan":null,"inf":null}'
JSON.stringify()
也会剥离那些值是函数或undefined
的属性:
const obj = { fn: function() {}, undef: undefined };
// 空对象。`JSON.stringify()` 移除了 functions 和 `undefined`.
JSON.stringify(obj); // '{}'
漂亮的打印
JSON.stringify()
的第一个参数是要序列化成JSON的对象。JSON.stringify()
实际上有三个参数,且第三个参数被称为spaces
。这个spaces
参数被用来做人为可读的方式去格式化JSON输出。
你可以将spaces
参数设置成一个字符串或者一个数字。如果spaces
不是undefined,JSON.stringify()
将JSON输入的key放在它自己的行上,并给每个key用spaces
当前缀。
const obj = { a: 1, b: 2, c: 3, d: { e: 4 } };
// '{"a":1,"b":2,"c":3,"d":{"e":4}}'
JSON.stringify(obj);
// {
// "a": 1,
// "b": 2,
// "c": 3,
// "d": {
// "e": 4
// }
// }
JSON.stringify(obj, null, ' ');
// 格式化JSON输出时,使用两个空格,见上述
JSON.stringify(obj, null, 2);
spaces
字符串不是非要都是空格,虽然实践中我们常将它设置成空格。比如:
// {
// __"a": 1,
// __"b": 2,
// __"c": 3,
// __"d": {
// ____"e": 4
// __}
// }
JSON.stringify(obj, null, '__');
替代
JSON.stringify()
的第二个参数是replacer
函数。在上面的例子中,replacer
是null
。JavaScript在对象的每组key/value对上调用这个替代函数,并使用这个替代函数返回的值。比如:
const obj = { a: 1, b: 2, c: 3, d: { e: 4 } };
// `replacer` 每个数字的值的增量是1,输入是:、
// '{"a":2,"b":3,"c":4,"d":{"e":5}}'
JSON.stringify(obj, function replacer(key, value) {
if (typeof value === 'number') {
return value + 1;
}
return value;
});
(未完全翻译,剩余内容请阅读原文)