本文介绍利用Function构造函数将JSON字符串转换为JS对象的高效方法。通过对比jQuery源码中的parseJSON实现,展示了该方法在Firefox浏览器中解析大量数据时,耗时仅55毫秒,远优于Eval的7234毫秒,验证了其在性能优化方面的显著优势。
jQuery源码中的JSON解析逻辑
在研读JQuery源码时,发现了一种解析JSON字符串的新思路,其实现方式令人印象深刻。
具体代码实现如下:
parseJSON: function( data ) {
if ( typeof data !== "string" || !data ) {
return null;
}
// 确保去除首尾空白字符(IE浏览器无法处理)
data = jQuery.trim( data );
// 验证传入数据是否为合法的JSON格式
// 逻辑参考自 http://json.org/json2.js
if ( /^[/],:{}/s]*$/.test(data.replace(///(?:["////bfnrt]|u[0-9a-fA-F]{4})/g, "@")
.replace(/"[^"///n/r]*"|true|false|null|-?/d+(?:/./d*)?(?:[eE][+/-]?/d+)?/g, "]")
.replace(/(?:^|:|,)(?:/s*/[)+/g, "")) ) {
// 优先尝试使用原生JSON解析器
return window.JSON && window.JSON.parse ?
window.JSON.parse( data ) :
(new Function("return " + data))();
} else {
jQuery.error( "Invalid JSON: " + data );
}
}Function构造函数解析原理
该方法的核心逻辑在于:
关键代码如下:
(new Function("return " + data))();这里利用了Function()构造函数,将JSON字符串作为函数体的数据传入,定义函数后立即执行,从而返回对应的JSON对象。
性能对比测试与结果
经过实际测试,使用这种方法解析JSON字符串的速度比使用Eval解析要快数百倍。
测试代码如下:
var jsonStr ="{";
for(var i=0;i<10000;i++){
jsonStr+="a"+i+":"+i+","
}
jsonStr = jsonStr.substring(0,jsonStr.length-1);
jsonStr+="}";
var date = new Date();
var start = date.getTime()
//var boj = (new Function("return "+jsonStr ))();
var boj = eval("("+jsonStr+")");
var date1 = new Date();
console.info(date1.getTime()-start);在Firefox浏览器下的测试结果中,Eval解析耗时7234毫秒,而使用Function构造函数方法仅耗时55毫秒,效率提升极为显著。