jQuery源码分析主要参考nuysoft的博客,主要用于个人的学习记录与总结。
jQuery源码总体架构:从总体上面来看jQuery的所有代码都被包含在这样一个自调用的匿名函数中。
(function(window,undefined){
//代码
})(window);
分析:
1.这样的一个自调用的匿名函数可以创建私有的命名空间,防止了命名冲突,避免破坏全局的命名空间。同时它可以立即执行一段代码,并把结果赋给变量;打破我们常规的先写函数,再调用的流程,简化书写。
2.匿名函数又叫函数直接量,有两种写法:
1 //这是立即调用函数使用的两种方式 2 (function(){ 3 console.log( this ); 4 console.log( arguments ); 5 }(window)); 6 7 (function(){ 8 console.log( this ); 9 console.log( arguments ); 10 }(window))
3.传入变量window,可以将全局变量window转变为局部变量,在jQuery代码中访问,不用在到全局的作用域中间去,可以更快的访问。将window作为参数,可以在压缩代码的时候优化:
1 (function(a,b){})(window);//window被优化为a
4.由于undefined可以被重写,赋新的值。为了确保undefined真的未定义,所以将其作为参数传入。
总体架构:
1 (function(window,undefined){ 2 3 var jQuery = function(selector,context){ 4 return new jQuery.fn.init(selector,context,rootjQuery); 5 } 6 /* 7 工具函数 8 异步队列Deferred 9 浏览器检测 Support 10 数据缓存 Data 11 队列 queue 12 属性操作 Attribute 13 事件处理 Event 14 选择器 Sizzle 15 DOM 遍历 16 DOM 操作 17 CSS 操作 18 异步请求 AJAX 19 动画 FX 20 坐标和大小 21 */ 22 23 })(window);
1 (function(window,undefined){ 2 //这里是外围调用的jQuery,即$ 3 var jQuery = (function(){ 4 //构建jQuery对象 5 var jQuery = function(selector,context){ 6 return new jQuery.fn.init(selector,context,rootjQuery); 7 } 8 //jQuery对象原型 9 jQuery.fn = jQuery.prototype={ 10 constructor:jQuery;//构造函数指向为jQuery 11 init:function(selector,context,rootjQuery){ 12 // selector有以下7种分支情况: 13 // DOM元素 14 // body(优化) 15 // 字符串:HTML标签、HTML字符串、#id、选择器表达式 16 // 函数(作为ready回调函数) 17 // 最后返回伪数组 18 } 19 } 20 //强制将jQuery.fn.init.prototype设置为jQuery.fn 21 jQuery.fn.init.prototype = jQuery.fn; 22 23 //合并内容到第一个参数中 后续的大部分扩展都是调用这个函数 24 jQuery.extend = jQuery.fn.extend = function(){} 25 26 //在jQuery上扩展静态方法 27 jQuery.extend({ 28 // ready bindReady 29 // isPlainObject isEmptyObject 30 // parseJSON parseXML 31 // globalEval 32 // each makeArray inArray merge grep map 33 // proxy 34 // access 35 // uaMatch 36 // sub 37 // browser 38 }); 39 40 // 到这里,jQuery对象构造完成,后边的代码都是对jQuery或jQuery对象的扩展 41 return jQuery; 42 })() 43 })(window);
先执行 jQuery.fn = jQuery.prototype,再执行 jQuery.fn.init.prototype = jQuery.fn,合并后的代码如下:
1 jQuery.fn.init.prototype=jQuery.fn=jQuery.prototype
所有有挂载到jQuery.fn的方法,相当于挂载到了jQuery.prototype,即挂载到了jQuery 函数上(一开始的 jQuery = function( selector, context ) ),但是最后都相当于挂载到了 jQuery.fn.init.prototype,即相当于挂载到了一开始的jQuery 函数返回的对象上,即挂载到了我们最终使用的jQuery对象上。
最终 jQuery对象由以下部分组成:
1,挂在jQuery.prototype.init中的this上的属性或方法。
2,挂在jQuery.prototype.init.prototype上的属性或方法。
3,因为把jQuery.prototype赋值给了jQuery.prototype.init.prototype,所以挂在jQuery.prototype上的属性和方法也是jQuery对象的一部分。
4,通过jQuery.fn.extend({...})方式扩展的属性或方法(后续提到)。