代码改变世界

jquery1.6.2源码拆分一

2011-09-05 15:25  飞魚  阅读(2089)  评论(4编辑  收藏  举报

jquery库是以(function (window, undefined) {...})(window);匿名函数传参的形式封装的,匿名函数可以避免污染外层变量,传参以减少作用域查找...

打开jquery1.6版本源码后,上千行代码看的这头昏眼花,同时jquery代码衔接的又很紧密,本文以调试的方式拆分...

这里用的是ff的firebug,没有用chrome的是因为逐行调试过程中页面经常崩溃...

先大概调试了下jquery的源码,在匿名函数内,函数是先解析的,然后在从顶部变量逐行解析,遇到型如()()的则马上执行...

jquery代码实在是多,贴几个重要部分说明..

声明几个变量,主要是声明的jQuery变量(外部jQuery变量),在它的内部又声明了一个jQuery变量(为了区分这里叫它内部jQ),内部jQ里面实例化了一个函数(init),在来看看这个函数...

它重写了内部jQ变量的原型(constructor:jQuery使重写后的原型对象和函数关联)

从这看出又重写了实例化的函数(init)的原型对象,把内部jQ的原型对象挂到了它上面...

紧接着就是后面的 jQuery.extend = jQuery.fn.extend = function () {

给内部jQ的原型对象添加了一个extend方法,主要用语扩展对象..

在往后就是一些扩展内部jQ的代码,然后返回这个内部jQ对象给外部jQuery变量...

在后面主要就是一些扩展这个外部jQuery变量对象和原型对象,如图

最后就是把这个外层jQuery变量(已经没了jQuery变量内外部之分,因为全都集成到了外部的jQuery变量上)赋给全局对象的俩个属性,如图

下面就拿如下图所示调用代码来调试,并拆分出jQuery的dom加载完后执行的代码

F11单步进入..一步步执行你会看到jQuery内部new了jQuery.fn.init(selector, context, rootjQuery);去执行init函数..

里面判断传进来的是一个函数

rootjQuery是jq库解析执行后返回的包装对象,如下图箭头所示

js里没有类的概念,但为了后面的说明更清楚,把jQuery变量当作一个类,这个类有很多属性和方法,类似oo语言的静态方法可直接调用,而调用jQuery()则返回一个实例对象,实例对象的属性和方法都是查找的构造函数本身或原型对象..

rootJquery.ready(selector),调用了类的ready方法

ready方法调用了bindReady方法,其实第一次进来时readyList为undefined

它调用了类的_Deferred方法,返回了声明的deferred对象,此时readyList不为undefined,返回readyList后下面判断文档是否加载完,如果加载完马上执行ready函数,注册的文档dom加载完和load事件,都是为了执行ready函数,因为有的时候页面很小,不敢保证dom加载完事件是否先于load,所以同事都注册了,且dom监听事件是执行后就会删除事件的...

ready方法执行完bindReady后,执行readyList.done(fn),把函数加入数组队列,如下图

当dom加载完或load先执行时,执行ready方法,如下图,注意这个是类的方法

执行一次后isReady=true,第二次调用不会在进入这个函数再次执行...

readyList.resolveWith执行数组队列中的函数

同时传递了docuement和jQuery,供内部函数直接用jQuery...

根据以上步骤和依赖函数拆分出了等待dom加载完后执行的一个代码库setupJq-v0.1.js下载

页面代码如上图,因为相应功能都去掉了,所以原生获取dom对象绑定事件,以后会在这个大体结构上扩建,因为水平有限,通过一步步搭建一个完整的jQuery库,相信然后就能简化出一个适合自己的版本了...