JQuery是一種基于JavaScript的快速、精簡的JavaScript庫。它簡化了HTML文檔遍歷、事件處理、動畫、以及Ajax交互等操作。JQuery庫的初始化是非常重要的,它為頁面的JavaScript代碼設置了全局上下文,包括在一個或多個匿名函數里加載jQuery庫、定義一個名為jQuery的全局對象,在jQuery原型上添加新的方法。因此,我們需要仔細研究jQuery庫的初始化源碼。
(function( global, factory ) { 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 ); } // Pass this if window is not defined yet }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { //定義全局的jQuery對象 var jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); }; //當前的jQuery庫版本 jQuery.fn = jQuery.prototype = { jquery: version, //當前jQuery對象的長度 length: 0, // ... 其他方法 ... }; // The init constructor // Used for instantiating a new jQuery object jQuery.fn.init = function( selector, context, root ) { // ... 初始化方法 ... }; // Attach jQuery functions to global object // Expose jQuery to the global object even when an AMD loader is used (as opposed // to acts like an anonymous module) by adding a property to // the global object. if ( !noGlobal ) { window.jQuery = window.$ = jQuery; } return jQuery; }));
通過上述代碼,我們可以看到jQuery庫的初始化過程和結構。其中,首先通過立即執行函數表達式(immediately-invoked function expression, IIFE)創建了一個作用域,可以避免jQuery中的變量污染全局。之后,判斷jQuery是使用exports還是返回即將定義的jQuery函數。對于前者,module.exports會被定義為true,之后會為運行環境exports注入一個factory函數。對于后者,直接調用factory函數即可。通過此操作,可以判斷在不同的運行環境下需要采用不同的AMD方法。
接著,在factory函數中,定義了一個jQuery函數,返回一個init構造函數生成的新的jQuery對象。在jQuery庫的prototype屬性中聲明了大量的方法,這些方法被添加到了jQuery對象中。當往jQuery對象添加函數時會自動添加到jQuery.prototype中,為所有的jQuery對象所繼承。init方法是通過判斷不同的傳參類型實現不同的初始化方式。最后通過noGlobal參數和window對象進行全局變量的定義和注入,使得其他的JavaScript代碼可以依賴jQuery庫調用這些函數和屬性。