jquery-2.1.4 源码解读(1):jquery架构

本人在研究jquery源码的过程中将同时记录下研究过程,此文将分阶段研究jquery源码,先是jquery的总体架构,然后是内部实现细节。

jquery代码结构大概为:

(function(global, factory){

...
jQuery = function(){ //73-77 定义jQuery函数对象
return new jQuery.fn.init(selector, context);
};
...
jQuery.fn = jQuery.prototype = {...}; //92-175 定义jQuery的原型
...
jQuery.extend = jQuery.fn.extend = function(){...}; //177-240 定义jQuery和jQuery原型中的extend方法
jQuery.extend({...}); //242-526 扩展jQuery函数对象,添加了一些基础通用方法如each(),trim()等
...
var Sizzle = (function(window){...}); 554-2612//定义选择器引擎Sizzle
...
jQuery.fn.extend({...}); //2676-2721 给jQuery原型添加选择器功能函数
jQuery.fn.init = function(){...}; //2734-2831 定义jQuery.prototype.init构造函数
jQuery.extend({...}); //2849-2876 扩展jQuery静态函数dir(),sibling(),用于遍历dom
jQuery.fn.extend({...}); //2878-2955 扩展jQuery原型方法,用于dom添加、查找等操作
...
jQuery.each({...}); //2962-3026 扩展jQuery原型方法,用于dom查找
...
jQuery.Callbacks = function(){...}; //3065-3227 扩展jQuery静态方法,用于管理回调函数队列
jQuery.extend({}); //3230-3369 扩展jQuery静态方法,为jQuery增加回调函数解决方案
jQuery.fn.ready = function(fn){...}; //3375-3380 定义ready
...
jQuery.ready.promise = function(obj){...} //3435-3458
jQuery.access = function(){...} //3467-3516 定义jQuery入口方法,供原型方法attr调用,提供重载功能
...
function Data(){...};Data.prototype={...}; //3534-3705 定义Data构造函数及原型
jQuery.extend({...});jQuery.fn.extend({...}); //3754-3878 扩展jQuery和jQuery.prototype的操作数据data方法
jQuery.extend({...});jQuery.fn.extend({...}); //3881-4012 扩展jQuery和jQuery.prototype的函数队列方法
...
jQuery.event={...};...;jQuery.fn.extend({...});//4083-4909 扩展jQuery和jQuery.prototype的事件处理方法
...
jQuery.extend({...});jQuery.fn.extend({...});//5041-5471 扩展jQuery和jQuery.prototype的元素增删改查操作
...
jQuery.extend({...});jQuery.fn.extend({...});//5909-6153 扩展处理css的方法
...
jQuery.each({...});... //6833-6910 扩展自定义动画效果
jQuery.fn.extend({...});jQuery.extend({...})...; //6945-7134 扩展处理dom属性的方法
...
jQuery.fn.extend({...}); //7168-7313 扩展处理class的方法
...
jQuery.each(...);jQuery.fn.extend({...}); //7478-7509 扩展事件处理方法
...jQuery.extend({...});...//7547-8897 扩展ajax方法
jQuery.offset={};... //8920-9144 扩展操作元素位置的方法
...

}(参数1, 参数2));

此处定义了匿名函数,然后传入参数1和参数2,立即执行,将代码放在匿名函数中执行,匿名函数有自己的执行环境,从而能够保证不会污染全局变量。

参数1为typeof window !== "undefined" ? window : this,如果window!==undefined则global=window,参数2处为jquery的主体部分,全局window将作为参数传递给参数2处定义的函数,参数2定义的函数末尾处将jquery赋值为全局window的属性,window.jQuery = window.$ = jQuery; 因此能够在全局环境下直接访问jquery。

jQuery的主要架构代码如下:

var jQuery = function(selector, context){
     return new jQuery.fn.init(selecor, context);
}
...
jQuery.fn = jQuery.prototype = {...};
...
jQuery.fn.init = function(selector, context){...}
...
jQuery.fn.init.prototype = jQuery.fn;
...
window.jQuery = jQuery;

fanctory(global)执行完毕后,即jquery源码被加载并执行完毕后,内存中的JS对象结构如下:

jQuery在以上架构的基础上,通过extend()each()方法向jQuery函数和jQuery.prototype中扩展了其他的方法。

上图的箭头表示了引用关系,如jquery.extend和jquery.fn.extend引用了同一个函数对象,jquery.fn和jquery.prototype引用了同一个函数对象。

jquery.fn 和 jquery.prototype指向了同一个原型对象,fn的作用在于将jquery.prototype简写。

在jquery函数对象上定义了一些静态函数,如extend()、isFunction()、each()、map()、isArray()、trim()、isPlainObject()等,可通过jquery.extend()方式来调用。

由代码73-77行可知,调用jquery方法即jquery(selector,contxt),实际上执行的是方法 return new jQuery.fn.init( selector, context );  这样我们在调用jquery方法时实际上返回的是一个jquery.fn.init构造函数的对象,可能有人会问,为什么在jquery方法中不直接返回一个对象呢?我们希望通过调用jquery方法后返回一个jquery类型的对象,如果在jquery(selector,context)方法中直接返回对象,则无法达到这个目的,而 jquery.prototype = jquery.prototype.init.prototype,所以通过new jquery.prototype.init(selector,contxt)创建的对象通过instanceof可判断出是jquery的实例,即new jQuery.prototype.init() instanceof jQuery 可返回true(因为new jQuery.prototype.init()._proto_ = jQuery.prototype,关于instancof的执行机制可查看另一篇文章javascript 中 instanceof 的执行机制)。

posted @ 2015-12-07 22:26  比昂  阅读(318)  评论(0编辑  收藏  举报