在网上下了一个jQuery 1.2.6的源码分析教程,看得似懂非懂,于是还是去github上下载源码,然后慢慢看源代码学习,首先来说说core.js这个核心文件吧。

jQuery整体的基本架构说起来也并不复杂,但是要看明白还是要花一点功夫,core.js这个文件搭建起了jQuery的整个框架,该文件的基本内容我大致总结如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//将整个jQuery 对象作为一个外部接口
var jQuery = (function(){
 
var jQuery = function( selector, context ) {
        //当执行形如$("p")的代码时会new一个jQuery.fn.init的对象,此对象一般我们称之为jQuery对象,下文中我将称其为jQuery实例对象,以与jQuery对象本身区分开来
        return new jQuery.fn.init( selector, context, rootjQuery );
    },/*
    ...
    此处包含一些其他的变量,如正则表达式,useragent等
    ...
    */
//此处之所以把jQuery的原型与jQuery.fn绑定是因为fn可以作为其短名称出现
jQuery.fn = jQuery.prototype = {
//jQuery对象的原型所在,其中的方法和属性可由jQuery实例对象访问
    init :function(){
        //用以构建jQuery实例对象,最后返回一个类数组对象
    },
    /*
    ...
 
    其他属性和方法,例如length,jquery版本,以及许多访问jquery数组元素的方法
    如:eq,get 等。
 
    ...
    */
}
//绑定jQuery对象的原型链
jQuery.fn.init.prototype = jQuery.fn;
 
//extend 可由 jQuery对象(静态方法)以及实例对象(实例方法)访问
jQuery.extend = jQuery.fn.extend =  function(){
    /*
    ...
    jQuery本身的所有内容几乎都是由extend方法所扩展的,包括jQuery插件机制也建立在此方法之上
    该方法,
    ...
    */
 
};
 
jQuery.extend({
    /*
    jQuery自身核心的一些方法和属性,
    包括 noConflict,isReady等
    */
});
 
/*
...
此处是一些其他操作,例如浏览器检测,处理ready事件等
...
*/
//最后返回jQuery供外部使用(作为全局对象)
return jQuery;
})();

可以看出jQuery大致分为两个部分,一个是静态方法部分,一个是实例对象部分,而这两者都是通过同一个函数extend来进行扩展的,也许上面代码看起来还比较抽象,下图则描述了整个框架的关系:

这样整个结构就显得清晰多了。其中最右边的jQuery实例是通过new jQuery.fn.init得到的。这样,扩展到jQuery.fn上的方法即可以作为实例方法供jQuery实例访问,而扩展到jQuery对象本身上的方法则作为静态方法。

在core.js中调用了extend来扩展绝大部分核心方法,首先来分析一下extend方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
jQuery.extend = jQuery.fn.extend = function() {
    var options, name, src, copy, copyIsArray, clone,
        target = arguments[0] || {}, //将第一个参数作为扩展的目标对象
        i = 1,
        length = arguments.length,
        deep = false;
 
    // Handle a deep copy situation
    //可以传递一个bool值进来用于表示扩展对象时是否是深拷贝
    if ( typeof target === "boolean" ) {
        deep = target;
        target = arguments[1] || {};
        // skip the boolean and the target
        i = 2;
    }
 
    // Handle case when target is a string or something (possible in deep copy)
    // 当扩展对象是字符串时
    if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
        target = {};
    }
 
    // extend jQuery itself if only one argument is passed
    if ( length === i ) {
    // 关键!!当调用$.extend时,this将绑定到jQuery对象上,此时扩展的方法或者属性将是静态的,
    // 而调用$.fn.extend时则绑定到jQuery.fn上,此时扩展的均是实例方法,我们在撰写插件时可以在方法内部使用this,此时的this指向的是jQuery的实例对象
        target = this;
        --i;//修正i,以便后面正确遍历对象
    }
    //以下便是扩展代码,既可以用于扩展jQuery,也可以用来扩展自定义的对象,此方法是公开的,更多可以参考jQuery文档
    for ( ; i < length; i++ ) {
        // Only deal with non-null/undefined values
        if ( (options = arguments[ i ]) != null ) {
            // Extend the base object
            for ( name in options ) {
                src = target[ name ];
                copy = options[ name ];
 
                // Prevent never-ending loop
                if ( target === copy ) {
                    continue;
                }
 
                // Recurse if we're merging plain objects or arrays
                // 如果是合并普通对象或者数组时,采用递归方式进行深拷贝(比如当数组中嵌套数组或者对象嵌套对象时)
                // 在jQuery内部核心扩展方法时并没有用到此段代码,比如下面的isPlainObject,isArray方法都是用extend扩展到jQuery中的。
                if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
                    if ( copyIsArray ) {
                        copyIsArray = false;
                        clone = src && jQuery.isArray(src) ? src : []; //
 
                    } else {
                        clone = src && jQuery.isPlainObject(src) ? src : {};
                    }
 
                    // Never move original objects, clone them
                    target[ name ] = jQuery.extend( deep, clone, copy );
 
                // Don't bring in undefined values
                } else if ( copy !== undefined ) {
                    target[ name ] = copy;
                }
            }
        }
    }
 
    // Return the modified object
    return target;
};

(转载)jQuery 1.6 源码学习(一)——core.js[1]之基本架构的更多相关文章

  1. (转载)jQuery 1.6 源码学习(二)——core.js[2]之extend&ready方法

    上次分析了extend方法的实现,而紧接着extend方法后面调用了jQuery.extend()方法(core.js 359行),今天来看看究竟core.js里为jQuery对象扩展了哪些静态方法. ...

  2. python源码学习(一)——python的总体架构

    python源码学习(一)——python的总体架构 学习环境: 系统:ubuntu 12.04 STLpython版本:2.7既然要学习python的源码,首先我们要在电脑上安装python并且下载 ...

  3. metamask源码学习-ui/index.js

    The UI-即上图左下角metamask-ui部分,即其图形化界面 The MetaMask UI is essentially just a website that can be configu ...

  4. chrome源码学习之:js与底层c++的通信

    以查询历史记录为例: 1.在上层history.js中通过chrome.send()来向底层发送事件请求和相关参数,其中'queryHistory'为信号名称,[this.searchText_, t ...

  5. vue 源码学习----build/config.js

    1. process 这个process是什么?为何都没有引入就可以使用了呢? process 对象是一个 global (全局变量),提供有关信息,控制当前 Node.js 进程.作为一个对象,它对 ...

  6. jquery 源码学习(一)

    从上边的注释看,jQuery的源码结构相当清晰.条理,不像代码那般晦涩和让人纠结   1. 总体架构 1.1 自调用匿名函数 self-invoking anonymous function 打开jQ ...

  7. jquery源码学习(一)——jquery结构概述以及如何合适的暴露全局变量

    jQuery 源码学习是对js的能力提升很有帮助的一个方法,废话不说,我们来开始学习啦 我们学习的源码是jquery-2.0.3已经不支持IE6,7,8了,因为可以少学很多hack和兼容的方法. jq ...

  8. jQuery源码学习感想

    还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码, ...

  9. jquery源码学习笔记三:jQuery工厂剖析

    jquery源码学习笔记二:jQuery工厂 jquery源码学习笔记一:总体结构 上两篇说过,query的核心是一个jQuery工厂.其代码如下 function( window, noGlobal ...

随机推荐

  1. iOS Library not loaded: Reason: image not found

    iOS Library not loaded: ReactiveCocoa.framework ...Reason: image not found 解决办法:BuildPhases中,将对应的框架的 ...

  2. 关于OJ1028的参考解法

    其中运用了最小公倍数与最大公约数乘积等于两数相乘的定理. #include <stdio.h> int main(int argc, char *argv[]) { int a,b,c,d ...

  3. 新接触PHP课程,给自己定制的目标

    PHP课程初接触,对自己的计划和展望恢复 从今天开始了为期四个半月的关于PHP课程的学习.从零开始接触一门新的技术知识,而且还是在短短四个月内就要掌握牢固,其实确确实实感觉不易.可是世间再没有路,不还 ...

  4. WinForm开发框架【细化权限至操作按钮】

    有不少园友经常问我程序有没有更新,真的很抱歉,最近因为工作原因一直很忙,导致程序有很长时间都没有更新了,首先在这里感谢关心俺的朋友们. 这几天好好看了一下原来的程序,还有很多地方需要改进,比如操作数据 ...

  5. Docker镜像文件存储结构

    docker相关文件存放在:/var/lib/docker目录下 镜像的存储结构主要分两部分,一是镜像ID之间的关联,一是镜像ID与镜像名称之间的关联,前者的结构体叫Graph,后者叫TagStore ...

  6. JVM 新生代老年代

    1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...

  7. 理论基础知识之————KB Kb Kbps 相关单位的区别和换算

    换算公式 8bit(位)=1Byte(字节) 1024Byte(字节)=1KB 1024KB=1MB 1024MB=1GB 1024GB=1TB 容量是大写的  B 而传输的速度是小写的  b bps ...

  8. myeclipse连接oracle步骤

    1.加载ojdbc.jar驱动(路径:E:\myoracle\oracle\product\11.2.0\dbhome_1\jdbc\lib) 2.String url = "jdbc:or ...

  9. 关于xml配置实现AOP的小知识

    除了前面介绍的基于JDK1.5的注解方式来定义切面,切入点和增强处理外,Spring AOP也允许直接使用XML配置文件来管理它们.在JDK1.5之前,只能使用配置文件的方式来管理,在Spring2. ...

  10. 【转】wpa_supplicant与wpa_cli之间通信过程

    [转]wpa_supplicant与wpa_cli之间通信过程 转自:http://blog.chinaunix.net/uid-26585427-id-4051479.html wpa_suppli ...