Safely turning a JSON string into an object

Safely turning a JSON string into an object

技术背景

[JSON][2] API 随着 ECMAScript 5 被引入,目前市场上超过 99% 的浏览器都实现了该 API。jQuery 曾经有一个 $.parseJSON() 函数,但在 jQuery 3.0 中已被弃用,实际上它长期以来只是 JSON.parse() 的包装器。

实现步骤

使用 JSON.parse() 方法

这是将 JSON 字符串转换为对象的纯 JavaScript 方法,只要确保使用的是较新的浏览器即可。示例代码如下:

1
2
3
let jsonString = '{"city": "Boston", "population": 500000}';
let jsonObject = JSON.parse(jsonString);
console.log(jsonObject.city, jsonObject.population);

处理异常情况

如果无法保证输入的字符串一定是有效的 JSON 格式,可以使用 try...catch 块来捕获可能的错误:

1
2
3
4
5
6
7
let jsonString = '{"city": "Boston", "population": 500000}';
let data;
try {
data = JSON.parse(jsonString);
} catch (error) {
data = { message: 'Server error, please retry' };
}

使用 reviver 函数

可以使用 reviver 函数对解析结果进行过滤或转换:

1
2
3
4
5
let jsonString = '{"city": "Boston", "population": 500000}';
let data = JSON.parse(jsonString, function reviver(key, value) {
// 这里可以添加过滤或转换逻辑
return value;
});

核心代码

基本的 JSON.parse() 使用

1
2
3
4
5
let jsonRes = '{ "students" : [' +
'{ "firstName":"Michel" , "lastName":"John" ,"age":18},' +
'{ "firstName":"Richard" , "lastName":"Joe","age":20 }, ' +
'{ "firstName":"James" , "lastName":"Henry","age":15 } ]}';
let studentObject = JSON.parse(jsonRes);

安全解析函数

1
2
3
4
5
6
7
8
9
10
11
12
13
JSON.safeParse = function (input, def) {
// 将 null 转换为空对象
if (!input) {
return def || {};
} else if (Object.prototype.toString.call(input) === '[object Object]') {
return input;
}
try {
return JSON.parse(input);
} catch (e) {
return def || {};
}
};

TypeScript 安全解析函数

1
2
3
4
5
6
7
export function safeJsonParse(str: string) {
try {
return JSON.parse(str);
} catch (e) {
return str;
}
}

最佳实践

处理不同类型的数据

  • 数组:当使用 JSON.parse() 解析从数组派生的 JSON 时,该方法将返回一个 JavaScript 数组。
1
2
let myArr = JSON.parse('["apple", "banana", "cherry"]');
console.log(myArr[0]);
  • 日期对象:JSON 中不允许使用日期对象,可以在解析后将字符串转换为日期对象。
1
2
3
let text = '{ "name":"John", "birth":"1986-12-14", "city":"New York"}';
let obj = JSON.parse(text);
obj.birth = new Date(obj.birth);
  • 函数:JSON 中不允许使用函数,如果需要包含函数,可以将其写成字符串,解析后再使用 eval 转换。
1
2
3
let text = '{ "name":"John", "age":"function () {return 30;}", "city":"New York"}';
let obj = JSON.parse(text);
obj.age = eval("(" + obj.age + ")");

深度克隆对象或数组

可以使用 JSON.stringify()JSON.parse() 的组合来实现对象或数组的深度克隆。

1
2
3
4
let arr2 = [1, 2, [3, 4]];
let newArrDeepclone = JSON.parse(JSON.stringify(arr2));
arr2[2][0] = 'changed';
console.log(newArrDeepclone); // 值未改变

常见问题

解析非有效 JSON 字符串

如果输入的字符串不是有效的 JSON 格式,JSON.parse() 会抛出 SyntaxError 异常。可以使用 try...catch 块来捕获并处理该异常。

性能问题

不同的解析方法在不同的浏览器和数据类型下性能有所不同。例如,eval/Function 方法在 Chrome 上对于小对象可能很快,但对于大的深层对象(N = 1000)可能会导致栈溢出错误;JSON.parse() 在 Safari 和 Firefox 上是最快的。可以参考 性能测试 了解更多细节。


Safely turning a JSON string into an object
https://119291.xyz/posts/safely-turning-a-json-string-into-an-object/
作者
ww
发布于
2025年6月17日
许可协议