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方法也加上去,那样就更麻烦了

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

时间: 2024-11-03 14:38:42

jQuery源码学习1——整体架构篇的相关文章

jQuery源码学习3——工具方法篇

基本工具方法结构如下: jQuery.extend({ init:function(){}, each:function(){}, className:{ add:function(){}, remove:function(){}, has:function(){}, }, swap:function(){}, css:function(){}, curCSS:function(){}, clean:function(){}, expr:{}, token:[], find:function()

Nmap 源码学习二 整体架构

目录功能: docs :相关文档 libdnet-stripped :开源网络接口库 liblinear:开源大型线性分类库 liblua:开源Lua脚本语言库 libnetutil:基本的网络函数 libpcap:开源抓包库 libpcre:开源正则表达式库 macosx:xcode项目文件 mswin32:vs项目文件 nbase:Nmap封装的基础使用函数库 ncat:netcat网络工具,由Nmap实现 ndiff:比较Nmap扫描结果的实用命令 nmap-update:负责Nmap更新

jquery源码学习-1-整体架构

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>jquery1.0.1</title> </head> <body> <script src="./jquery.1.0.1.js"></script> <script> // console.log($()) /*

jQuery源码学习笔记:总体架构

1.1.自调用匿名函数: (function( window, undefined ) { // jquery code })(window); 这是一个自调用匿名函数,第一个括号内是一个匿名函数,第二个括号立即执行,传参是window. 1.为什么有自调用匿名函数? 通过定义匿名函数,创建了一个"私有"空间,jQuery必须保证创建的变量不能和导入它的程序发生冲突. 2.为什么传入window? 传入window使得window由全局变量变成局部变量,jQuery访问window时,

转载Aaron博客 ---- jQuery 2.0.3 源码分析core - 整体架构

jQuery 2.0.3 源码分析core - 整体架构 整体架构 拜读一个开源框架,最想学到的就是设计的思想和实现的技巧. 废话不多说,jquery这么多年了分析都写烂了,老早以前就拜读过, 不过这几年都是做移动端,一直御用zepto, 最近抽出点时间把jquery又给扫一遍 我也不会照本宣科的翻译源码,结合自己的实际经验一起拜读吧! github上最新是jquery-master,加入了AMD规范了,我就以官方最新2.0.3为准 整体架构 jQuery框架的核心就是从HTML文档中匹配元素并

jQuery 源码学习 - 01 - 简洁的 $(&#39;...&#39;)

首先贴上学习参考资料:[深入浅出jQuery]源码浅析--整体架构,备用地址:chokcoco/jQuery-. jQuery 库,js 开发的一个里程碑,它的出现,让网页开发者们告别荒蛮的上古时代,初步解放生产力,正式进入黄铜时代. 虽然如今 Angular/React/Vue 三驾马车驰骋畋猎,jQuery的时代渐行渐远,但是它的思想它的设计都有着里程碑式的作用.当然,我是拿它来补基础的,逃... 1.自执行函数 (function(params) { // ... })(Variable)

jquery源码学习

jQuery 源码学习是对js的能力提升很有帮助的一个方法,废话不说,我们来开始学习啦 我们学习的源码是jquery-2.0.3已经不支持IE6,7,8了,因为可以少学很多hack和兼容的方法. jquery-2.0.3的代码结构如下 首先最外层为一个闭包, 代码执行的最后一句为window.$ = window.jquery = jquery 让闭包中的变量暴露倒全局中. 传参传入window是为了便于压缩 传入undefined是为了undifined被修改,他是window的属性,可以被修

菜鸟的jQuery源码学习笔记(二)

jQuery对象是使用构造函数和原型模式相结合的方式创建的.现在来看看jQuery的原型对象jQuery.prototype: 1 jQuery.fn = jQuery.prototype = { 2 //成员变量和方法 3 } 这里给原型对象起了一个别名叫做jQuery.fn.要注意的是这个jQuery.fn可不是jQuery对象的属性,而是jQuery构造方法本身的属性,它是不会传给它所创建的对象的.如果你在控制台敲$().fn的话输出的结果会是undefined.接下来看看原型对象里面有些

jquery源码学习(一)core部分

这一部分是jquery的核心 jquery的构造器 jquery的核心工具函数 构造器 jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQu