惰性載入函數(shù)

因為瀏覽器之間行為的差異,多數(shù)JavaScript 代碼包含了大量的if 語句窒朋,將執(zhí)行引導(dǎo)到正確的代碼中争拐∫钢啵看看下面來自上一章的createXHR()函數(shù)。
function createXHR(){
if (typeof XMLHttpRequest != "undefined"){
return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined"){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp"],
i,len;
for (i=0,len=versions.length; i < len; i++){
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex){
//跳過
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
} else {
throw new Error("No XHR object available.");
}
}
每次調(diào)用createXHR()的時候,它都要對瀏覽器所支持的能力仔細(xì)檢查隘冲。首先檢查內(nèi)置的XHR金赦,然后測試有沒有基于ActiveX 的XHR,最后如果都沒有發(fā)現(xiàn)的話就拋出一個錯誤对嚼。每次調(diào)用該函數(shù)都是這樣夹抗,即使每次調(diào)用時分支的結(jié)果都不變:如果瀏覽器支持內(nèi)置XHR,那么它就一直支持了纵竖,那么這種測試就變得沒必要了漠烧。即使只有一個if 語句的代碼,也肯定要比沒有if 語句的慢靡砌,所以如果if 語句不必每次執(zhí)行已脓,那么代碼可以運行地更快一些。解決方案就是稱之為惰性載入的技巧通殃。

  • 惰性載入表示函數(shù)執(zhí)行的分支僅會發(fā)生一次度液。有兩種實現(xiàn)惰性載入的方式,第一種就是在函數(shù)被調(diào)用時再處理函數(shù)画舌。在第一次調(diào)用的過程中堕担,該函數(shù)會被覆蓋為另外一個按合適方式執(zhí)行的函數(shù),這樣任何對原函數(shù)的調(diào)用都不用再經(jīng)過執(zhí)行的分支了曲聂。例如霹购,可以用下面的方式使用惰性載入重寫
    createXHR()。
    function createXHR(){
    if (typeof XMLHttpRequest != "undefined"){
    createXHR = function(){
    return new XMLHttpRequest();
    };
    } else if (typeof ActiveXObject != "undefined"){
    createXHR = function(){
    if (typeof arguments.callee.activeXString != "string"){
    var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
    "MSXML2.XMLHttp"],
    i, len;
    for (i=0,len=versions.length; i < len; i++){
    try {
    new ActiveXObject(versions[i]);
    arguments.callee.activeXString = versions[i];
    break;
    } catch (ex){
    //skip
    }
    }
    }
    return new ActiveXObject(arguments.callee.activeXString);
    };
    } else {
    createXHR = function(){
    throw new Error("No XHR object available.");
    };
    }
    return createXHR();
    }
    在這個惰性載入的createXHR()中朋腋,if 語句的每一個分支都會為createXHR 變量賦值齐疙,有效覆
    蓋了原有的函數(shù)。最后一步便是調(diào)用新賦的函數(shù)旭咽。下一次調(diào)用createXHR()的時候贞奋,就會直接調(diào)用被分配的函數(shù),這樣就不用再次執(zhí)行if 語句了穷绵。

  • 第二種實現(xiàn)惰性載入的方式是在聲明函數(shù)時就指定適當(dāng)?shù)暮瘮?shù)轿塔。這樣,第一次調(diào)用函數(shù)時就不會損失性能了请垛,而在代碼首次加載時會損失一點性能催训。以下就是按照這一思路重寫前面例子的結(jié)果。
    var createXHR = (function(){
    if (typeof XMLHttpRequest != "undefined"){
    return function(){
    return new XMLHttpRequest();
    };
    } else if (typeof ActiveXObject != "undefined"){
    return function(){
    if (typeof arguments.callee.activeXString != "string"){
    var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
    "MSXML2.XMLHttp"],
    i, len;
    for (i=0,len=versions.length; i < len; i++){
    try {
    new ActiveXObject(versions[i]);
    arguments.callee.activeXString = versions[i];
    break;
    } catch (ex){
    //skip
    }
    }
    }
    return new ActiveXObject(arguments.callee.activeXString);
    };
    } else {
    return function(){
    throw new Error("No XHR object available.");
    };
    }
    })();
    這個例子中使用的技巧是創(chuàng)建一個匿名宗收、自執(zhí)行的函數(shù)漫拭,用以確定應(yīng)該使用哪一個函數(shù)實現(xiàn)實際的邏輯都一樣。不一樣的地方就是第一行代碼(使用var 定義函數(shù))混稽、新增了自執(zhí)行的匿名函數(shù)采驻,另外每個分支都返回正確的函數(shù)定義审胚,以便立即將其賦值給createXHR()。
    惰性載入函數(shù)的優(yōu)點是只在執(zhí)行分支代碼時犧牲一點兒性能礼旅。至于哪種方式更合適膳叨,就要看的具體需求而定了。不過這兩種方式都能避免執(zhí)行不必要的代碼痘系。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末菲嘴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子汰翠,更是在濱河造成了極大的恐慌龄坪,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件复唤,死亡現(xiàn)場離奇詭異健田,居然都是意外死亡,警方通過查閱死者的電腦和手機佛纫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門妓局,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呈宇,你說我怎么就攤上這事好爬。” “怎么了攒盈?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵抵拘,是天一觀的道長。 經(jīng)常有香客問我型豁,道長,這世上最難降的妖魔是什么尚蝌? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任迎变,我火速辦了婚禮,結(jié)果婚禮上飘言,老公的妹妹穿的比我還像新娘衣形。我一直安慰自己,他們只是感情好姿鸿,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布谆吴。 她就那樣靜靜地躺著,像睡著了一般苛预。 火紅的嫁衣襯著肌膚如雪句狼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天热某,我揣著相機與錄音腻菇,去河邊找鬼胳螟。 笑死,一個胖子當(dāng)著我的面吹牛筹吐,可吹牛的內(nèi)容都是我干的糖耸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼丘薛,長吁一口氣:“原來是場噩夢啊……” “哼嘉竟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起洋侨,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤舍扰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后凰兑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妥粟,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年吏够,在試婚紗的時候發(fā)現(xiàn)自己被綠了勾给。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡锅知,死狀恐怖播急,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情售睹,我是刑警寧澤桩警,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站昌妹,受9級特大地震影響捶枢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜飞崖,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一烂叔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧固歪,春花似錦蒜鸡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蒲讯,卻和暖如春忘朝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背伶椿。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工辜伟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留氓侧,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓导狡,卻偏偏與公主長得像约巷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子旱捧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容