用Closure模仿Singleton

 Thu, 02 Apr 2009 14:44:31 +0800

最近需要修改以前寫過的試算網頁,就把舊的code拿出來看了一下,試跑時發現裡面用的取得XmlHttpRequest物件的方法不是很有效率。因為我沒有用到非同步機制,只是把他當作一個動態IO的方法,其實不需要使用多個XmlHttpRequest物件,所以就想把他改寫成Singleton。

舊的方法是我從mozilla網站上抄來的,像這樣:

function xmlhttp() {
    try{ return new ActiveXObject("Msxml2.XMLHTTP.6.0") }catch(e){}
    try{ return new ActiveXObject("Msxml2.XMLHTTP.3.0") }catch(e){}
    try{ return new ActiveXObject("Msxml2.XMLHTTP") }catch(e){}
    try{ return new ActiveXObject("Microsoft.XMLHTTP") }catch(e){}
    try{ return new XMLHttpRequest();} catch(e){}
    return null;
}

這樣每次執行xmlhttp函數來取得XmlHttpRequest物件時,都要跑過幾次try catch。但是把他改寫成這樣的話,就有singleton的效果了:

var xmlhttp = function() {
    var ajax = function() {
        try{ return new ActiveXObject("Msxml2.XMLHTTP.6.0") }catch(e){}
        try{ return new ActiveXObject("Msxml2.XMLHTTP.3.0") }catch(e){}
        try{ return new ActiveXObject("Msxml2.XMLHTTP") }catch(e){}
        try{ return new ActiveXObject("Microsoft.XMLHTTP") }catch(e){}
        try{ return new XMLHttpRequest();} catch(e){}
        return null;
    }();
    return function(){return ajax;};
}();

這樣要用到的變數在一開始就產生了,所以呼叫函數的時候其實只是把這個變數回傳而已。