jjQuery 源码分析1: 整体结构
目前阅读的是jQuery 1.11.3的源码,有参考nuysoft的资料。
原来比较喜欢在自己的Evernote上做学习基类,并没有在网上写技术博客的习惯,现在开始学习JS的开源代码,想跟大家多交流,希望有所收获。
1 (function( global, factory ) { 2 if ( typeof module === "object" && typeof module.exports === "object" ) { 3 module.exports = global.document ? 4 factory( global, true ) : 5 function( w ) { 6 if ( !w.document ) { 7 throw new Error( "jQuery requires a window with a document" ); 8 } 9 return factory( w ); 10 }; 11 } else { 12 factory( global ); 13 } 14 }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 15 16 17 18 // 创建jQuery对象, 实际上是jQuery.fn.init所返回的对象 19 20 var jQuery = function( selector, context ) { 21 22 return new jQuery.fn.init( selector, context ); 23 24 // 如果调用new jQuery, 生成的jQuery会被丢弃,最后返回jQuery.fn.init对象 25 26 // 因此可以直接调用jQuery(selector, context), 不需要使用new 27 } 28 29 30 31 // 创建jQuery对象原型,为jQuery添加各种方法 32 33 jQuery.fn = jQuery.prototype = { 34 35 // 在调用new jQuery.fn.init后, jQuery.fn.iniy.prototype = jQuery.fn = jQuery.prototype 36 37 // 相当于将所有jQuery.fn的方法都挂载到一开始jQuery函数返回的对象上 38 39 ... 40 41 } 42 43 init.prototype = jQuery.fn; 44 45 46 47 // 创建jQuery.extend方法 48 49 jQuery.extend = jQuery.fn.extend = function() { 50 51 ... 52 53 } 54 55 56 57 // 使用jQuery.extend扩展静态方法 58 59 jQuery.extend({}); 60 61 62 63 // 为window全局变量添加$对象 64 65 66 if ( typeof noGlobal === strundefined ) { // var strundefined = typeof undefined 67 68 window.jQuery = window.$ = jQuery; 69 70 } 71 72 73 74 return jQuery; 75 76 }));
为了保证不污染全局变量,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
// 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);