博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jQuery源码学习1——整体架构篇
阅读量:4983 次
发布时间:2019-06-12

本文共 8471 字,大约阅读时间需要 28 分钟。

由于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

你可能感兴趣的文章