JsModule

jQuery源碼分析系列
JS的模塊化

最近在使用kendo ui的時候遇到一些問題,有一個需求是希望在打開LOV組件的時候不執(zhí)行查詢操作。但是在kendo官網(wǎng)上并沒有看到任何有關(guān)LOV的文檔或者API,于是猜想LOV可能是公司基于kendo ui封裝的一個組件。經(jīng)過查看源碼發(fā)現(xiàn)確實如此,所有代碼都在kendo.all.js 這個文件中,差不多7W行的代碼,能找到LOV組件的實現(xiàn)代碼著實是依賴于IDEA這個強大的工具。問題最終得到解決,稍微修改一下部分源代碼,可以滿足這個需求,而且發(fā)現(xiàn)這個LOV組件在設(shè)計之初確實沒有提供一個參數(shù)來選擇是否在打開的時候查詢,這其實算是一個比較通用的需求,應(yīng)該算是設(shè)計上的一點缺陷吧。沒有見過LOV的童鞋這里可以給你們展示一下,它是長這樣的:
初始化的時候,是長這樣的,和一個普通的 輸入框 很像,箭頭標注的地方就是LOV



當(dāng)我們點擊那個小小的搜索按鈕時,會彈出一個窗口,窗口中的內(nèi)容更像是一個Grid,如圖:



當(dāng)我們雙擊grid中的一行記錄的時,會把值重新帶回到界面的那個輸入框中。

這里展示了LOV組件的基本使用,在實際開發(fā)中,配置這樣的一個LOV只需要短短的幾分鐘,可以節(jié)約大量的時間成本。當(dāng)然還有很多細節(jié),這里不過多介紹,因為這是需要前端和后臺一起支持才能使用的。
需求可以實現(xiàn)了,這給了我極大的信心,畢竟從這么多代碼里找出一部分然后修改一部分也很有意思。于是在修改之后又去看了一部分kendo ui的源碼,感覺還好,有很多地方并不清楚,但是大概能知道什么意思,我目前要的就是這個效果,也不指望能馬上明白每一行代碼的用意,這需要特別特別扎實的基礎(chǔ)功,我目前是做不到的。效果還是有一些的,很多之前不知道的API在源碼里面都可以看到,這至少對我之后在使用kendo時是有幫助的,另一個好處就是讓我明確了目前這一階段在前端這一塊的學(xué)習(xí)方向:JQuery。kendo 中到處都是JQuery,因為之前簡單的看過一點點JQuery源碼,那時候根本一點都看不懂,但還是有一點點印象。雖然我菜,但是我有一顆學(xué)習(xí)的心啊,當(dāng)時就覺得JQuery很重要,我想看它的目的也不是想要完全理解這個庫,而是希望通過學(xué)習(xí)它來幫助自己對JS一些特性的理解,在學(xué)習(xí)的過程中會遇到各種各樣的問題,然后就會有針對性的去找文檔、查資料,我覺得這種學(xué)習(xí)方式很好。

閉包與IIFE

什么是閉包?我覺得我肯定是說不清楚的,或者我根本就沒理解吧,因為在很多情況下,我并不知道那到底屬不屬于閉包,JS太靈活了。網(wǎng)上找了一點說明,可能時間久了就有感覺了吧。

閉包就是一個函數(shù)引用另外一個函數(shù)的變量,因為變量被引用著所以不會被回收,因此可以用來封裝一個私有變量。

function a(){
  var n = 0;
  function inc(){
    n++; 
    console.log(n);
  }
  return inc;
}
var c = a();
c();  //控制臺輸出1
c();  //控制臺輸出2

有權(quán)訪問另一個函數(shù)作用域內(nèi)變量的函數(shù)都是閉包。

  • 一個陷阱
function createFunctions(){
  var result = new Array();
  for (var i=0; i < 10; i++){
    result[i] = function(){
      return i;
    };
  }
  return result;
}
var funcs = createFunctions();
for (var i=0; i < funcs.length; i++){
  console.log(funcs[i]());
}

輸出結(jié)果不是 0-9, 而是10 個 10 !
這里面這句話是關(guān)鍵 “閉包就是一個函數(shù)引用另外一個函數(shù)的變量,因為變量被引用著所以不會被回收”。
在這段JS中,for語句塊并沒有自己的作用域,也就是說 i 的作用域是屬于 createFunctions 函數(shù)的。這里的 匿名函數(shù)訪問了 createFunctions 函數(shù)里面的 i 變量,所以形成了一個閉包。

  for (var i=0; i < 10; i++){
    result[i] = function(){
      return i;
    };
  }

在執(zhí)行完這段循環(huán)之后,i 的值變成了 10 ,而在 i 變成 10 之前, 函數(shù)并沒有調(diào)用。函數(shù)帶()才是執(zhí)行函數(shù)!
所以在執(zhí)行以下語句的時候,i 的值已經(jīng)是 10 了。

for (var i=0; i < funcs.length; i++){
  console.log(funcs[i]());
}

IIFE(Immediately-Invoked Function Expression),即 立即調(diào)用的函數(shù)表達。
比如,下面就是一個 立即執(zhí)行函數(shù)

;(function (參數(shù)) {
  // 模塊代碼
  // return something;
})(參數(shù)));

它的結(jié)構(gòu)可以看作是以下三部分組成:;、匿名函數(shù)、()
最后的一對括號是對匿名函數(shù)的調(diào)用,因此必不可少。而前面的一對圍繞著函數(shù)表達式的一對括號并不是必需的,但它可以用來給開發(fā)人員一個指示 – 這是一個 IIFE。也有一些開發(fā)者在函數(shù)表達式前面加上一個驚嘆號(!)或分號(;),而不是用括號包起來:

!function (參數(shù)) {
  // 代碼
  // return something
}(參數(shù));

還可以用一個大括號包起來

(function (參數(shù)) {
  // 代碼
  // return something
}(參數(shù)));

在有些人的代碼中,將 undefined 作為上面代碼中的一個參數(shù),他們那樣做是因為 undefined 并不是 JavaScript 的保留字,用戶也可以定義它,這樣,當(dāng)判斷某個值是否是 undefined 的時候,判斷可能會是錯誤的。將 undefined 作為一個參數(shù)傳入,是希望代碼能按預(yù)期那樣運行。

(function (參數(shù)1, undefined ) {
  // 代碼
  // return something
}(參數(shù)1));

如上,當(dāng)傳入入第二個參數(shù)的時候, undefined 就是真正的undefined。
我為什么要一開始的時候就寫這個?因為JQuery一開始就是這么干的啊,不光是JQuery,大部分框架一開始都是這么干的。作為一個技術(shù),我覺得如果我想理解JQuery,我一開始就想知道這開頭代碼是什么意思,要不然心里不舒服。So,I have no choice.

了解了這個,下面可以開始看看源碼了,版本 3.3.1。

( function( global, factory ) {

    "use strict";

    if ( typeof module === "object" && typeof module.exports === "object" ) {

        // For CommonJS and CommonJS-like environments where a proper `window`
        // is present, execute the factory and get jQuery.
        // For environments that do not have a `window` with a `document`
        // (such as Node.js), expose a factory as module.exports.
        // This accentuates the need for the creation of a real `window`.
        // e.g. var jQuery = require("jquery")(window);
        // See ticket #14549 for more info.
        module.exports = global.document ?
            factory( global, true ) :
            function( w ) {
                if ( !w.document ) {
                    throw new Error( "jQuery requires a window with a document" );
                }
                return factory( w );
            };
    } else {
        factory( global );
    }

// Pass this if window is not defined yet
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {

    //代碼

});

傳入兩個參數(shù),第二個參數(shù)是一個 函數(shù),JQuery的主要代碼,就是在這個函數(shù)中實現(xiàn)。其實這里面涉及到另一個知識點,JS模塊。有關(guān)于JS模塊的內(nèi)容,在文章的開頭處已經(jīng)給了相關(guān)鏈接。

if ( typeof module === "object" && typeof module.exports === "object" ) {
}

這只是對JS執(zhí)行環(huán)境的一個檢測,判斷當(dāng)前的JS執(zhí)行環(huán)境是在瀏覽器,還是支持 CommonJS Modules 規(guī)范。與 CommonJS Modules 對應(yīng)的,還有 AMD,還有就是ES6 標準的模塊化解決方案。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,283評論 6 530
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 97,947評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,094評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,485評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,268評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,817評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,906評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,039評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,551評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,502評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,662評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,188評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,907評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,304評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,563評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,255評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,637評論 2 370

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