javascript中惰性载入函数
在<javascript高级程序设计>这本书中看到的,在此做一下记录, 感觉还是很有用的. 就从大家都知道的创建xhr对象方法说起
我们都知道如果创建一个xhr对象(不会写,不怕,有百度,嘿嘿)
function createXHR(){
if (typeof XMLHttpRequest != "undefined"){
return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined"){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],
i,len;
for (i=0,len=versions.length; i < len; i++){
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex){
//跳过
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
} else {
throw new Error("No XHR object available.");
}
}
这个函数相信大家都见过,每次调用createXHR的时候,都要检测浏览器是否支持XMLHttpRequest对象,里面基本上都是一层一层的if…else… 还有 try…catch….每次都这样,想想也烦.
看看书中的方法:
第一种方法
function createXHR(){
if (typeof XMLHttpRequest != "undefined"){
createXHR = function(){
return new XMLHttpRequest();
};
} else if (typeof ActiveXObject != "undefined"){
createXHR = function(){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],
i, len;
for (i=0,len=versions.length; i < len; i++){
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex){
//skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
};
} else {
createXHR = function(){
throw new Error("No XHR object available.");
};
}
return createXHR();
}
这里我们发现, 每一次分支都会对createXHR赋值 , 在第一次执行createXHR的时候,如果有内置的XMLHttpRequest对象,createXHR函数会被覆盖,下次再调用的时候,就会调用已经被覆盖的createXHR函数,直接返回一个XMLHttpRequest对象,其他的分支也是类似的, 最后一步就是调用新的createXHR函数
这里的情景是:浏览如果支持内置的XHR或者基于ActiveX的XHR,就会一直支持,在这种情况下,其实只需要一次检测就够了,所以覆盖createXHR是合适的
第二种方法
var createXHR = (function(){
if (typeof XMLHttpRequest != "undefined"){
return function(){
return new XMLHttpRequest();
};
} else if (typeof ActiveXObject != "undefined"){
return function(){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"],
i, len;
for (i=0,len=versions.length; i < len; i++){
try {
new ActiveXObject(versions[i]); arguments.callee.activeXString = versions[i];
break;
} catch (ex){
//skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
};
} else {
return function(){
throw new Error("No XHR object available.");
};
}
})();
第二种其实和第一种逻辑上是一样的,只不过多了第一行代码(使用var定义函数)、新增了自执行的匿名函数
总体来说,这个惰性载入函数还是有点价值的吧,只是牺牲一点性能和代码量,就能减少不必要执行的代码,但是注意会覆盖原来的函数…