在 javascript 程式碼中,因為各瀏覽器之間的行為的差異,我們經常在函數中包含了大量的 if 語句,以檢查瀏覽器特性,解決不同瀏覽器的兼容問題。 例如,我們最常見的為dom 節點新增事件的函數:
function addEvent (type, element, fun) {
if (element.addEventListener) {
element.addEventListener(type, fun, false);
}
else if(element. {
element.attachEvent('on' type, fun);
}
else{
element['on' type] = fun;
}
}
每次呼叫addEvent 函數的時候,它都要對瀏覽器所支援的能力進行檢查,首先檢查是否支援addEventListener 方法,如果不支持,再檢查是否支援attachEvent 方法,如果還不支持,就用dom 0 級的方法加入事件。 這個過程,在addEvent 函數每次調用的時候都要走一遍,其實,如果瀏覽器支援其中的一種方法,那麼他就會一直支持了,就沒有必要再進行其他分支的檢測了, 也就是說,if 語句不必每次都執行,程式碼可以運行的更快一些。
解決的方案就是稱為惰性載入的技巧。
所謂惰性載入,就是說函數的if分支只會執行一次,之後呼叫函數時,直接進入所支援的分支程式碼。 有兩種實現惰性載入的方式,第一種事函數在第一次呼叫時,對函數本身進行二次處理,該函數會被覆寫為符合分支條件的函數,這樣對原函數的呼叫就不用再經過執行的分支了, 我們可以用下面的方式使用惰性載入重寫addEvent()。
function addEvent (type, elellement >if (element.addEventListener) {
addEvent = function (type, element, fun) {
element.addEventListener(type, fun, false);
}
}
else if( element.attachEvent){
addEvent = function (type, element, fun) {
element.attachEvent('on' type, fun);
}
}
else{
addEvent = function (type, element, fun) {
element['on' type] = fun;
}
}
return addEvent(type, element, fun);
}
在這個惰性載入的addEvent() 中,if 語句的每個分支都會為addEvent 變數賦值,有效覆寫了原始函數。 最後一步便是呼叫了新賦函數。下次呼叫 addEvent() 的時候,就會直接呼叫新賦值的函數,這樣就不用再執行if 語句了。
第二種實作惰性載入的方式是在宣告函數時就指定適當的函數。 這樣在第一次呼叫函數時就不會損失效能了,只在程式碼載入時會損失一點效能。 一下就是按照這一思路重寫的 addEvent()。
var addEvent = (function () {
if (document.addEventListener) {
return function (type, element, fun) {
element.addEventListener(type, fun, false);
}
}
else if (document. ) {
return function (type, element, fun) {
element.attachEvent('on' type, fun);
}
}
else {
return function (type , element, fun) {
element['on' type] = fun;
}
}
})();
這個例子所使用的技巧是創建一個匿名的自執行函數,透過不同的分支以確定應該使用那個函數實現,實際的邏輯都一樣, 不一樣的地方就是使用了函數表達式(使用了var 定義函數)和新增了一個匿名函數,另外每個分支都傳回一個正確的函數,並立即將其賦值給變數addEvent。
惰性載入函數的優點只執行一次if 分支,避免了函數每次執行時候都要執行if 分支和不必要的程式碼,因此提升了程式碼效能,至於那種方式更合適,就要看您的需求而定了。