一、eval
eval()可以动态解析和执行字符串,它直接把字符串当做Javascript代码执行,我们可以利用这个特性用来进行JSON数据的解析
不过由于eval可以解析任何字符串,所以是不安全的
var a = '{"test" : 123}';
var b = eval("(" + a + ")");
二、JSON.parse
这是浏览器(除ie8以下)自带的解析json字符串的方法,JSON.parse对解析的json字符串格式要求十分严格,需要是标准格式的JSON字符串
var a = '{"test":123}'; JSON.parse(a);
三、new Function()
new Function(arg1, arg2, ...argN, function_body);
new Function可以动态解析和执行字符串,所以可以利用其构造一个自执行函数来进行JSON字符串的解析
var a = '{"test":123}'; var jo = new Function("return" + a)()
不过使用new Function会创建一个本地对象,导致内存无法进行释放,如果解析的字符串内容过多,就有可能导致很多内存在解析完成后无法释放
一个简单的测试代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <button onclick="clickFn()">ce</button> </body> <script> function clickFn() { for(var a = 0; a < 100000 ;a ++){ var text = '{"test":"..."}'; // if ( window.JSON && window.JSON.parse ) { // window.JSON.parse(text); // } new Function("return " + text)(); } } </script> </html>
其中可以将循环次数改成10,增加字符串的内容
通过谷歌浏览器的性能分析可以看出来,每次点击之后进行JSON字符串解析,内存都会增长30多M
而且可以看出增长的都是SystemObjects,没法进行释放
如图:

使用eval方法也是如此

反观使用window.JSON.parse方法就不会出现这种情况

所以推荐大家最好使用浏览器自带的JSON字符串解析方法
顺便补充一下,jquery也有JSON字符串解析的方法$.parseJSON(data)
他其实也是用了浏览器的JSON.parse方法进行解析,遇到不支持JSON.parse的再使用new Function解析
相关源码如下:
parseJSON: function( data ) { // Attempt to parse using the native JSON parser first if ( window.JSON && window.JSON.parse ) { return window.JSON.parse( data ); } if ( data === null ) { return data; } if ( typeof data === "string" ) { // Make sure leading/trailing whitespace is removed (IE can't handle it) data = jQuery.trim( data ); if ( data ) { // Make sure the incoming data is actual JSON // Logic borrowed from http://json.org/json2.js if ( rvalidchars.test( data.replace( rvalidescape, "@" ) .replace( rvalidtokens, "]" ) .replace( rvalidbraces, "" ) ) ) { return ( new Function( "return " + data ) )(); } } } jQuery.error( "Invalid JSON: " + data ); },
浙公网安备 33010602011771号