目前閱讀的是jQuery 1.11.3的原始碼,有參考nuysoft的資料。原來比較喜歡在自己的Evernote上做學習基類,並沒有在網上寫技術部落格的習慣,現在開始學習JS的開原始碼,想跟大家多交流,希望有所收穫。
原始碼分析
(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 );
}
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
// 建立jQuery物件, 實際上是jQuery.fn.init所返回的物件
var jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context );
// 如果呼叫new jQuery, 生成的jQuery會被丟棄,最後返回jQuery.fn.init物件
// 因此可以直接呼叫jQuery(selector, context), 不需要使用new
}
// 建立jQuery物件原型,為jQuery新增各種方法
jQuery.fn = jQuery.prototype = {
// 在呼叫new jQuery.fn.init後, jQuery.fn.iniy.prototype = jQuery.fn = jQuery.prototype
// 相當於將所有jQuery.fn的方法都掛載到一開始jQuery函式返回的物件上
...
}
init.prototype = jQuery.fn;
// 建立jQuery.extend方法
jQuery.extend = jQuery.fn.extend = function() {、
...
}
// 使用jQuery.extend擴充套件靜態方法
jQuery.extend({});
// 為window全域性變數新增$物件
if ( typeof noGlobal === strundefined ) { // var strundefined = typeof undefined
window.jQuery = window.$ = jQuery;
}
return jQuery;
}));
window物件檢測
為了保證不汙染全域性變數,jQuery原始碼中將所有的物件及方法建立都放到了factory函式中執行。通過形參global來傳遞window變數,在利用factory建立jQuery物件以前,首先進行window變數的檢測。
window檢測程式碼部分有英文註釋
// For CommonJS and CommonJS-like environments where a proper window is present,
// execute the factory and get jQuery
// For environments that do not inherently posses a window with a document
// (such as Node.js), expose a jQuery-making 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 和 module.exports主要是為了讓jQuery能夠以模組的形式注入到沒有window.document變數的諸如Node.js的執行環境中,當遇到這種情況,就不會在window中設定jQuery$變數。要使用jQuery時,則是使用所返回的jQuery物件,如在Node.js中:
var jQuery = require("jquery")(window);