jQuery源码学习1——整体架构篇

由于jQuery的源码比较复杂,所以我选择从jQuery1.0.0版本开始学习,逐步深入。

而且本系列文章包含大量的个人观点,纯属本人学习的记录

jQuery1.0.0只有1800行左右的代码,相对来讲看起来还是比较简单的

首先,想说一下我对jQuery的理解

jQuery其实就是一个很大的构造函数

它为我们提供了很多实例化方法

当然,由于在js中函数本身就是对象

因此jQuery也提供了很多的静态方法

个人认为,这些静态方法更为底层

今天把jQuery的架构梳理了一下

其实我们可以将其中的方法抽出来,这样看起来就像是一个大的构造函数

function jQuery(){}
jQuery.prototype={
    jquery:    "",
    size:    function(){},
    get:    function(){},
    each:    function(){},
    index:    function(){},
    attr:    function(){},
    css:    function(){},
    text:    function(){},
    wrap:    function(){},
    append:    function(){},
    prepend:function(){},
    before:    function(){},
    after:    function(){},
    end:    function(){},
    find:    function(){},
    clone:    function(){},
    filter:    function(){},
    not:    function(){},
    add:    function(){},
    is:    function(){},
    domManip:function(){},
    pushStack:function(){},
    extend:    function(){},    //*扩展其他实例化对象方法的核心方法
    appendTo:    function(){}, //*通过macros的to 扩展的方法
    prependTo:    function(){}, //*通过macros的to 扩展的方法
    insertBefore:    function(){}, //*通过macros的to 扩展的方法
    insertAfter:    function(){}, //*通过macros的to 扩展的方法
    width:        function(){}, //*通过macros的css扩展的方法
    height:        function(){}, //*通过macros的css扩展的方法
    top:        function(){}, //*通过macros的css扩展的方法
    left:        function(){}, //*通过macros的css扩展的方法
    position:    function(){}, //*通过macros的css扩展的方法
    float:        function(){}, //*通过macros的css扩展的方法
    overflow:    function(){}, //*通过macros的css扩展的方法
    color:        function(){}, //*通过macros的css扩展的方法
    background:    function(){}, //*通过macros的css扩展的方法
    eq:        function(){}, //*通过macros的filter扩展的方法
    lt:        function(){}, //*通过macros的filter扩展的方法
    gt:        function(){}, //*通过macros的filter扩展的方法
    contains:    function(){}, //*通过macros的filter扩展的方法
    val:        function(){}, //*通过macros的attr扩展的方法
    html:        function(){}, //*通过macros的attr扩展的方法
    id:        function(){}, //*通过macros的attr扩展的方法
    title:        function(){}, //*通过macros的attr扩展的方法
    name:        function(){}, //*通过macros的attr扩展的方法
    href:        function(){}, //*通过macros的attr扩展的方法
    src:        function(){}, //*通过macros的attr扩展的方法
    rel:        function(){}, //*通过macros的attr扩展的方法
    parent:        function(){}, //*通过macros的axis扩展的方法
    ancestors:    function(){}, //*通过macros的axis扩展的方法
    parents:    function(){}, //*通过macros的axis扩展的方法
    next:        function(){}, //*通过macros的axis扩展的方法
    prev:        function(){}, //*通过macros的axis扩展的方法
    siblings:    function(){}, //*通过macros的axis扩展的方法
    children:    function(){}, //*通过macros的axis扩展的方法
    removeAttr:    function(){}, //*通过macros的each扩展的方法
    show:        function(){}, //*通过macros的each扩展的方法
    hide:        function(){}, //*通过macros的each扩展的方法
    toggle:        function(){}, //*通过macros的each扩展的方法
    addClass:    function(){}, //*通过macros的each扩展的方法
    removeClass:    function(){}, //*通过macros的each扩展的方法
    toggleClass:    function(){}, //*通过macros的each扩展的方法
    remove:        function(){}, //*通过macros的each扩展的方法
    empty:        function(){}, //*通过macros的each扩展的方法
    bind:        function(){}, //*通过macros的each扩展的方法
    unbind:        function(){}, //*通过macros的each扩展的方法
    trigger:    function(){}, //*通过macros的each扩展的方法
    _toggle:    function(){}, 
    toggle:        function(){},
    hover:        function(){},
    ready:        function(){},
    blur:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    focus:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    load:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    resize:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    scroll:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    unload:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    click:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    dbclick:    function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    mousedown:    function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    mouseup:    function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    mousemove:    function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    mouseover:    function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    mouseout:    function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    change:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    reset:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    select:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    submit:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    keydown:    function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    keypress:    function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    keyup:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    error:        function(){}, //*同时绑定了un解绑定方法和one只触发一次的方法
    //*由于上面已经定义过一个show方法,所以这里通过_show将其存储起来,否则下面的show方法会将其覆盖
    _show:        function(){}, //*动画方法
    show:        function(){},
    _hide:        function(){},
    hide:        function(){},
    slideDown:    function(){},
    slideUp:    function(){},
    slideToggle:    function(){},
    fadeIn:        function(){},
    fadeOut:    function(){},
    fadeTo:        function(){},
    animate:    function(){},
    queue:        function(){},
    loadIfModified:    function(){}, //*ajax方法
    load:        function(){},
    ajaxStart:    function(){},
    ajaxStop:    function(){},
    ajaxComplete:    function(){},
    ajaxError:    function(){},
    ajaxSuccess:    function(){}
};
jQuery.extend=    function(){};
jQuery.init=    function(){};
jQuery.each=    function(){};
jQuery.className={};
jQuery.swap=    function(){};
jQuery.css=    function(){};
jQuery.curCSS=    function(){};
jQuery.clean=    function(){};
jQuery.expr=    function(){};
jQuery.token=    function(){};
jQuery.find=    function(){};
jQuery.getAll=    function(){};
jQuery.attr=    function(){};
jQuery.parse=    [];
jQuery.filter=    function(){};
jQuery.trim=    function(){};
jQuery.parents=    function(){};
jQuery.sibling=    function(){};
jQuery.merge=    function(){};
jQuery.grep=    function(){};
jQuery.map=    function(){};
jQuery.event=    {};
jQuery.browser=    function(){};    //*browser方法要基于变量b b=navigator.userAgent.toLowerCase();
jQuery.boxModel=function(){};    //*boxModel方法要基于browser方法
jQuery.macros=    {};        //*由此派生出若干实例化对象的方法
jQuery.isReady=    false;        //*load模块
jQuery.readyList=[];
jQuery.ready=    function(){};
jQuery.setAuto=    function(){};    //*动画模块
jQuery.speed=    function(){};
jQuery.queue=    function(){};
jQuery.dequeue=    function(){};
jQuery.fx=    function(){};
jQuery.get=    function(){};    //*ajax模块
jQuery.getIfModified=function(){};
jQuery.getScript=function(){};
jQuery.post=    function(){};
jQuery.timeout=    0;
jQuery.ajaxTimeout=function(){};
jQuery.lastModifed=function(){};
jQuery.ajax=    function(){};
jQuery.active=    0;
jQuery.httpSuccess=function(){};
jQuery.httpModified=function(){};
jQuery.httpData=function(){};
jQuery.param=    function(){};

当然这里面省略了很多的细节

在梳理的过程中,发现了很多的问题,如下:

1、看到jQuery.macros的时候感觉很晕,后来才发现macros其实是把相关的方法或者属性名放到了一起,在合适的时机去初始化

例如macros.to下面的appendTo prependTo insertBefore insertAfter这四个方法就是在DOM模块被初始化的

2、v1.0.0对于避免污染全局空间的做法是用new function(){}形成封闭空间,由于之前本人一直用(function(){xxx})();来处理此类情况

所以看到new function(){}有些无所适从,后来通过查阅相关资料才发现这种方法其实相当于new Aaa;

new是js中的一个单目运算符,new后面的方法名的括号是可以省略的,所以完整的写法应该是new function(){}() 其中function(){}就相当于一个函数名

new function(){}通常用来初始化一些东西,但又没有污染全局对象

3、梳理到动画模块的时候,看到有_show和show两个方法瞬间石化了,不知道是干啥的,

经过高手指点才发现,在之前的实例化方法中,已经有一个show方法了,所以在定义第二个show方法的时候先用了一个_show方法将第一个show方法存了起来,

之所以存期来,是因为第二个show方法中需要调用第一个show方法

附带一句个人之拙见:jQuery的作者为什么不再起一个别的名字额外定义一个方法呢?非得弄成两个同名的方法,还用一个变量缓冲,搞不明白John Resig是怎么想的

hide和_hide也是同样的道理

4、本以为作者在处理两个名字一样的方法时就会通过_xxx来存储,但是例外出现在load,我很惊奇的发现实例化对象中有两个load方法

这样一来后面的load不就覆盖了前一个load了吗?后来定睛一看才发现后面的这个load方法可以大大方方的覆盖前一个load方法,没有任何关系

因为后面一个load方法实现了前一个load方法的所有功能,而且还扩展了和ajax相关的新的功能

但是感觉还是不对劲,既然后面的能实现,为什么前面还写一个load方法,感觉前面的load方法定义的既重复又没用

不过后来经过仔细分析,发现我又错了,因为第一个load方法是通过如下方法加到jQuery的实例化对象上的:

   var e = ("blur,focus,load,resize,scroll,unload,click,dblclick," +
        "mousedown,mouseup,mousemove,mouseover,mouseout,change,reset,select," + 
        "submit,keydown,keypress,keyup,error").split(",");
for ( var i = 0; i < e.length; i++ ) new function(){ var o = e[i]; jQuery.fn[o] = function(f){ return f ? this.bind(o, f) : this.trigger(o); }; jQuery.fn["un"+o] = function(f){ return this.unbind(o, f); }; jQuery.fn["one"+o] = function(f){
       .....
}; };

也就是说,人家除了绑定load方法之外还绑定了unload和oneload方法,要是按照我当初想的那样来变量e中去掉load的话

后面ajax模块还得将unload和oneload方法也加上去,那样就更麻烦了

所以采用了现在前面定义再覆盖的形式

转载于:https://www.cnblogs.com/zhaohuiziwo901/p/4950719.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值