在前端開發過程中必然繞不開jQuery庫,移動端zepto。天天用到的一個庫,很久就想通讀一下源碼,行動力不夠一直沒有執行……現在終於開始學習它,參照網上大神的博文和教程輔助自己學習。自己同時也構建一個自己的jQuery庫,體驗造輪子的整個過程。計划就是這樣子啦,下面就是行動!
jQuery源碼可以精簡為以下內容:

1 (function( global, factory ) { 2 3 if ( typeof module === "object" && typeof module.exports === "object" ) { 4 5 module.exports = global.document ? 6 factory( global, true ) : 7 function( w ) { 8 if ( !w.document ) { 9 throw new Error( "jQuery requires a window with a document" ); 10 } 11 return factory( w ); 12 }; 13 } else { 14 factory( global ); 15 } 16 17 }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 18 19 var jQuery = function( selector, context ) { 20 return new jQuery.fn.init( selector, context ); 21 }; 22 23 jQuery.fn = jQuery.prototype = {}; 24 //核心方法 25 //回歸調用 26 //異步隊列 27 //數據緩存 28 //隊列操作 29 //選擇器引 30 //屬性操作 31 //節點遍歷 32 //文檔處理 33 //樣式操作 34 //屬性操作 35 //事件體系 36 //ajax交互 37 //動畫引擎 38 return jQuery; 39 }));
方框上面的代碼是對AMD規范的支持。
jQuery整體上被包裹在一個匿名函數中,這個匿名函數再作為另一個匿名函數的參數被傳入,形參factory。
"()"圓括號包裹函數聲明語句,解析器會將其解析為表達式,再在后面加一對圓括號就會形成表達式調用:
(function(arg1,arg2){ //代碼 }(arg1,arg2));
包裹jQuery的匿名函數相當於arg2參數,在匿名參數中被調用——factory()。
這種被稱為命名空間的函數(或自執行函數、立即調用表達式函數)在開發中應該經常用到,原理可以參考我的另一篇博文:立即調用表達式。
jQuery對象的創建和調用方式
jQuery並沒有使用new運算符將jQuery顯式的實例化,而是直接調用其函數。如:
$().ready();
$().ajax();
源碼的最后部分有這樣一段代碼:
window.jQuery = window.$ = jQuery;
其實我們在平時的使用中就知道,$=jQuery,$("selector") = jQuery("selector"),$()、jQuery()直接調用自身就創建了對象。這里有着非常精妙的設計。
由以上代碼可以看出,jQuery()調用自身,獲得的是jQuery.fn.init對象。接着看init和jQuery的關系
先執行jQuery.fn = jQuery.protorype,再執行jQuery.fn.init.prototype = jQuery.fn,合並后是:
jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype;
即jQuery的prototype等於init的prototype
所以,所有掛載到jQuery.fn上的方法就是掛在到了jQuery.prototype,即掛在到了jQuery函數上,相當於掛載到了jQuery.fn.init.prototype上,即相當於掛載到了一開始的jQuery函數返回的對象上,即掛載到了我們最終使用的jQuery對象上。
參考:
慕課網jQuery源碼解析 ——Aaron
jQuery源碼分析系列——nuysoft