JavaScript 函式惰性載入

謙行發表於2013-08-11

最近看JavaScript高階程式設計,大有收穫,接下來幾天寫一下讀書筆記。之前寫了一篇Ajax初步理解的隨筆,裡面有個函式用來建立XmlHttpRequest物件,瀏覽器相容性原因,寫出的程式碼通過大量if判斷或者try,catch語句將函式引導到正確程式碼處。

<script type="text/javascript">
            function createXHR(){
                var xhr = null;
                try {
                    // Firefox, Opera 8.0+, Safari,IE7+
                    xhr = new XMLHttpRequest();
                }
                catch (e) {
                    // Internet Explorer 
                    try {
                        xhr = new ActiveXObject("Msxml2.XMLHTTP");
                    }
                    catch (e) {
                        try {
                            xhr = new ActiveXObject("Microsoft.XMLHTTP");
                        }
                        catch (e) {
                            xhr = null;
                        }
                    }
                }
                return xhr;
            }
        </script>

每次呼叫這個函式的時候,都要先進行瀏覽器能力檢查,首先檢查瀏覽器是否支援內建的XMLHyypRequest物件,如果不支援然後檢查各版本基於ActiveX的XMLHttpRequest,每次呼叫該函式都是這樣,其實當第一次執行完後,如果瀏覽器支援某個特定XMLHttpRequest物件,那麼下次執行的時候這種支援性並不會改變,沒必要再進行一邊檢測,即使只有一個if語句,執行也肯定比沒有要慢,如果我們可以讓if語句不必每次執行,那麼就可以在頻繁呼叫的情況下提高執行速度。解決方案就是稱之為惰性載入的技巧。

惰性載入

惰性載入表示函式執行的分支只會在函式第一次掉用的時候執行,在第一次呼叫過程中,該函式會被覆蓋為另一個按照合適方式執行的函式,這樣任何對原函式的呼叫就不用再經過執行的分支了。createXHR函式可以被改寫為這樣

function createXHR(){
                var xhr=null;
                if(typeof XMLHttpRequest !='undefined'){
                    xhr = new XMLHttpRequest();
                    createXHR=function(){
                        return new XMLHttpRequest();
                    }
                }else{
                    try {
                        xhr = new ActiveXObject("Msxml2.XMLHTTP");
                        createXHR=function(){
                            return new ActiveXObject("Msxml2.XMLHTTP");
                        }
                    }
                    catch (e) {
                        try {
                            xhr = new ActiveXObject("Microsoft.XMLHTTP");
                            createXHR=function(){
                                return new ActiveXObject("Microsoft.XMLHTTP");
                            }
                        }
                        catch (e) {
                            createXHR=function(){
                                return null;
                            }
                        }
                    }
                }
                return xhr;
            }

在這個惰性載入的createXHR中第一次執行的時候每個分支都會為createXHR重新賦值,覆蓋原函式,返回xhr物件,而第二次執行的時候就會直接呼叫重寫後的函式,這樣就不必執行每個分支重新做檢測了。

優點

惰性載入函式有兩個主要優點,第一是顯而易見的效率問題,雖然在第一次執行的時候函式會意味賦值而執行的慢一些,但是後續的呼叫會因為避免的重複檢測更快;第二個是要執行的適當程式碼只有當實際呼叫函式是才執行,很多JavaScript庫在在載入的時候就根據瀏覽器不同而執行很多分支,把所有東西實現設定好,而惰性載入函式將計算延遲,不影響初始指令碼的執行時間。

相關文章