JQuery源碼解析(一)

來源:互聯網
上載者:User

標籤:success   win   解析   需要   錯誤   get   define   它的   尋找   

jQuery使使用者能更方便地處理DOM、事件、實現動畫效果,並且方便地為網站提供AJAX互動。

2、jQuery的模組依賴網:

jQuery一共13個模組,模組不是單一的,比如jQuery動畫,都會依賴非同步隊列、動畫隊列、回調隊列與資料緩衝模組等。

jQuery抽出了所有可複用的特性,分離出單一模組,通過組合的用法,不管在設計思路與實現手法上jQuery都是非常高明的。

五大塊:選取器、DOM操作、事件、AJAX與動畫

那麼為什麼有13個模組?因為jQuery的設計中最喜歡的做的一件事,就是抽出共同的特性使之“模組化”,

當然也是更貼近S.O.L.I.D五大原則的“單一職責SRP”了,遵守單一職責的好處是可以讓我們很容易地來維護這個對象,

比如,當一個對象封裝了很多職責的時候,一旦一個職責需要修改,勢必會影響該對象的其它職責代碼。

通過解耦可以讓每個職責更加有彈性地變化。
我們來看看jQuery文檔針對業務層的Ajax的處理提供了一系列的門面介面:

.ajaxComplete().ajaxError().ajaxSend().ajaxStart().ajaxStop().ajaxSuccess()

 底層介面:

jQuery.ajax()jQuery.ajaxSetup()

 快捷方法:

jQuery.get()jQuery.getJSON()jQuery.getScript()jQuery.post()

 jQuery介面的設計原理

商務邏輯是複雜多變的,jQuery的高層API數量非常多,而且也非常的細緻,這樣做可以更友好的便於開發人員的操作,

不需要必須在一個介面上重載太多的動作。我們在深入內部看看Ajax的高層方法其實都是統一調用了一個靜態jQuery.ajax方法,

代碼見右側代碼編輯器(27-43行)。
在jQuery.ajax的內部實現是非常複雜的,首先ajax要考慮非同步處理與回調的統一性,

所以就引入了非同步隊列模組(Deferred)與回調模組(Callbacks), 所以要把這些模組方法在ajax方法內部再次封裝成、

構建出一個新的jQXHR對象,針對參數的預設處理,資料轉送的格式化等等。

 

二:立即調用運算式

任何庫與架構設計的第一個要點就是解決命名空間與變數汙染的問題。

jQuery就是利用了JavaScript函數範圍的特性,採用立即調用運算式包裹了自身的方法來解決這個問題。

jQuery的立即調用函數運算式的寫法有三種:

寫法1:

(function(window, factory) {    factory(window)}(this, function() {    return function() {       //jQuery的調用    }}))

 可以看出上面的代碼中嵌套了2個函數,而且把一個函數作為參數傳遞到另一個函數中並且執行,這種方法有點複雜,我們簡化一下寫法:

寫法2:

var factory = function(){    return function(){        //執行方法    }}var jQuery = factory();

 上面的代碼效果和方法1是等同的,但是這個factory有點變成了簡單的Factory 方法模式,需要自己調用,不像是一個單例的jQuery類,所以我們需要改成“自執行”,而不是另外調用。

寫法3:

(function(window, undefined) {    var jQuery = function() {}    // ...    window.jQuery = window.$ = jQuery;})(window);

 從上面的代碼可看出,自動初始化這個函數,讓其只構建一次。詳細說一下這種寫法的優勢:

  1、window和undefined都是為了減少變數尋找所經過的scope範圍。當window通過傳遞給閉包內部之後,

在閉包內部使用它的時候,可以把它當成一個局部變數,顯然比原先在window scope下尋找的時候要快一些。
  2、undefined也是同樣的道理,其實這個undefined並不是JavaScript資料類型的undefined,而是一個普普通通的變數名。

只是因為沒給它傳遞值,它的值就是undefined,undefined並不是JavaScript的保留字。

 

為什麼要傳遞undefined?

Javascript 中的 undefined 並不是作為關鍵字,因此可以允許使用者對其賦值。

 var undefined = ‘孫麗媛‘ ;(function(window) { alert(undefined);//IE8 ‘孫麗媛‘ })(window)

IE8存在這個問題,當然,大部分瀏覽器都是不能被修改的

如果函數調用不傳遞,參數預設就是undefined

;(function(window,undefined) {    //undefined})(window)

 

jQuery為什麼要建立這樣的一個外層包裹,其原理又是如何?

這裡要區分2個概念一個是匿名函數,一個是自執行。顧名思義,匿名函數,就是沒有函數名的函數,也就是不存在外部參考。但是是否像下面代碼實現呢:

function(){//代碼邏輯}

 上面這種寫法是錯了,聲明了它但是又不給名字又沒有使用,所以在文法上錯誤的,那麼怎麼去執行一個匿名的函數呢?
要調用一個函數,我們必須要有方法定位它、引用它。所以,我們要取一個名字:

var jQuery = function(){//代碼邏輯}

 jQuery使用()將匿名函數括起來,然後後面再加一對小括弧(包含參數列表),那麼這小括弧能把我們的運算式組合分塊,

並且每一塊(也就是每一對小括弧),都有一個傳回值。這個傳回值實際上也就是小括弧中運算式的傳回值。

所以,當我們用一對小括弧把匿名函數括起來的時候,實際上小括弧返回的,就是一個匿名函數的Function對象。

因此,小括弧對加上匿名函數就如同有名字的函數般被我們取得它的引用位置了。

所以如果在這個引用變數後面再加上參數列表,就會實現普通函數的調用形式。

最後,我們回到寫法1看看jQuery利用寫法3的寫法,然後把整個函數作為參數傳遞給另外一個函數,

主要是為了判斷jQuery在不同平台的下的載入邏輯,主流的庫一般都有對 AMD 和 CommonJS 的支援代碼,看看jQuery的代碼:

if (typeof module === "object" && typeof module.exports === "object") {    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);}

 總結:全域變數是魔鬼, 匿名函數可以有效保證在頁面上寫入JavaScript,而不會造成全域變數的汙染,

通過小括弧,讓其載入的時候立即初始化,這樣就形成了一個單例模式的效果從而只會執行一次。

 

JQuery源碼解析(一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.