ECMAScript 2016(ES7)新特性之修复 JSON.stringify() 关于 Infinity 和 NaN 的问题
JSON.stringify()
是在 JavaScript 中非常常用的方法,用来将对象转换为 JSON 字符串。然而,有时候这个方法会遇到一些边缘情况,比如处理 Infinity 或 NaN,会使得结果出现一些意想不到的问题。ECMAScript 2016(ES7)引入了一些新特性,解决了这些问题。
Infinity 和 NaN 的问题
在之前的版本中,如果我们对一个对象中包含 Infinity 或 NaN 的属性调用 JSON.stringify()
方法,会将它们转换成 null。例如:
JSON.stringify({a: Infinity, b: NaN}); // '{"a":null,"b":null}'
这显然不是我们期望的结果。考虑如下对象:
const obj = { name: 'John', age: NaN, money: Infinity };
此时使用 JSON.stringify()
就会产生错误的行为:
JSON.stringify(obj); // '{"name":"John","age":null,"money":null}'
由于 NaN 和 Infinity 均不是有效的 JSON 值,所以它们被转换为 null。这样做不仅容易误导,而且它可能会导致一些安全漏洞。
解决方法
ES7 引入了两个新的 JSON 全局对象方法:JSON.stringify()
中的 reviver 函数和 JSON.parse()
中的 replacer 函数。
reviver 函数是一个可选的参数,用于控制 JSON 解析结果中的每个属性。当 JSON 解析器(使用 JSON.parse()
)有解析到一个新属性时,它会调用 reviver 函数来转换属性值。在这里,我们可以识别 Infinity 和 NaN 并改变它们的值。
以下是一个示例:
// javascriptcn.com code example const obj = { name: 'John', age: NaN, money: Infinity }; // 利用 stringify 和 parse 进行复制 const newObj = JSON.parse(JSON.stringify(obj), (key, value) => { if (value === Infinity) { return 'Infinity'; } else if (typeof value === 'number' && isNaN(value)) { return 'NaN'; } return value; }); console.log(newObj); // 输出 {name: "John", age: "NaN", money: "Infinity"}
在这个示例中,我们传递了一个函数到 JSON.parse()
的第二个参数(称之为 reviver 函数)。该函数根据属性值的类型匹配它们并返回正确的变换结果。
结论
在任何编程语言中,要进行严格的验证和转换。在使用 JSON 时,我们需要特别注意 Infinity 和 NaN 的问题。使用 ES7 引入的 reviver 函数,可以轻松地解决这个问题。
总之,记得在使用 JSON.stringify()
和 JSON.parse()
时要小心,特别是在处理 NaN 和 Infinity 的时候。)
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/672f605beedcc8a97c8e2a2b