首页 » 编写高质量代码:改善JavaScript程序的188个建议 » 编写高质量代码:改善JavaScript程序的188个建议全文在线阅读

《编写高质量代码:改善JavaScript程序的188个建议》建议72:惰性载入函数

关灯直达底部

惰性载入函数主要解决的问题也是兼容性,原理跟分支函数类似,下面是简单的示例。


var addEvent=function(el,type,handle){

addEvent=el.addEventListener?function(el,type,handle){

el.addEventListener(type,handle,false);

}:function(el,type,handle){

el.attachEvent("on"+type,handle);

};

//在第一次执行addEvent函数时,修改了addEvent函数之后,必须执行一次

addEvent(el,type,handle);

}


从代码上看,惰性载入函数也是在函数内部改变自身的一种方式,这样在重复执行的时候就不会再进行兼容性方面的检测了。

惰性载入表示函数执行的分支仅会发生一次,即第一次调用的时候。在第一次调用的过程中,该函数会被覆盖为另一个按合适方式执行的函数,这样任何对原函数的调用都不用再经过执行的分支了。其优点如下:

❑要执行的适当代码只有在实际调用函数时才执行。

❑尽管第一次调用该函数会因额外的第二个函数调用而稍微慢点,但后续的调用都会很快,因为避免了多重条件。

由于浏览器之间的行为差异,多数JavaScript代码包含了大量的if语句,将执行引导到正确的代码中。

在下面惰性载入的createXHR中,if语句的每个分支都会为createXHR变量赋值,有效覆盖了原有的函数,最后一步便是调用新赋函数。下次调用createXHR的时候,就会直接调用被分配的函数,这样就不用再次执行if语句。


function createXHR{

if(typeof XMLHttpRequest!='undefined'){

return new XMLHttpRequest;

}else if(typeof ActiveXObject!='undefined'){

if(typeof arguments.callee.activeXString!='string'){ver

versions=["MSXML2.XMLHttp","MSXML2.XMLHttp.3.0","MSXML2.

XMLHttp.6.0"];

for(var i=0,len=versions.length;i<len;i++){

try{

var xhr=new ActiveXObject(versions[i]);

arguments.callee.activeXString=versions[i];

return xhr;

}catch(ex){

//跳过

}

}

}

return new ActiveXObject(arguments.callee.activeXString);

}else{

throw new Error("No XHR object available.");

}

}


每一次调用createXHR时都要对浏览器所支持的功能仔细检查,这样每次调用createXHR时都要进行相同的测试就变得没有必要了。减少if语句使其不必每一次都执行,代码就会执行得快些。解决方案就是惰性载入的技巧。


function createXHR{

if(typeof XMLHttpRequest!='undefined'){

createXHR=function{

return new XMLHttpRequest;

};

}else if(typeof ActiveXObject!='undefined'){

createXHR=function{

if(typeof arguments.callee.activeXString!='string'){ver

versions=["MSXML2.XMLHttp","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp.6.0"];

for(var i=0,len=versions.length;i<len;i++){

try{

var xhr=new ActiveXObject(versions[i]);

arguments.callee.activeXString=versions[i];

return xhr;

}catch(ex){

//跳过

}

}

}

return new ActiveXObject(arguments.callee.activeXString);

};

}else{

createXHR=function{

throw new Error("No XHR object available.");

};

}

return createXHR;

}


如前面所述,if语句的每一个分支都会为createXHR变量赋值,有效覆盖了原有函数。最后一步便是调用新赋函数,下次调用creatXHR的时候就会直接调用被分配的函数,这样就不用再次执行if语句。