讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議72:惰性載入函數 >

建議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語句。