JavaScript的JSON.stringify的80/20原则

原文信息: 查看原文查看原文

The 80/20 Guide to JSON.stringify in JavaScript

- Valeri Karpov

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有一个属性,这个属性的值是objJSON.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()NaNInfinity转化成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函数。在上面的例子中,replacernull。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;
});

(未完全翻译,剩余内容请阅读原文)

分享于 2020-01-07

访问量 991

预览图片