jQuery源码浅析一

导语:
如何提高编程能力,这几乎是媒体们采访一些编程大神的必问的问题,大部分大神都会提到多读源码,本人觉得确实有道理,因为源码中的一些方法或者思想确实能够让我们跳出自己的思维模式,拓展我们的编程思维。下面我们就来浅析jQuery源码部分知识。

jQuery源码差不多有上万行代码了,下面是其各部分的架构(在博客园上拷贝的一张图):

Paste_Image.png

**(一)、总体框架 **

首先我们来总体看下jquery的代码:

(function(window, undefined) {
   // jQuery 代码
})(window);

通过上面我们很容易看到jQuery的实现方法都被包含在立即执行函数中了,这样我们在引用jQuery时就马上执行了,并且jQuery里面的变量不会污染外界的变量。(对于单独暴露出的$及jQuery这两个参数其也做了防冲突处理这个我们在下一点将会谈到)。其中我们还看到在这个立即执行函数中在外界传了一个“window”参数,其本身有两个形参---一个是window另一个是undefined。那么为什么形参中有undefined的呢?这其实是针对更早期的环境当中(pre-ES5,eg. Internet Explorer 8)的undefined,因为在那个环境中undefined可以被改写,这样做确保jQuery里面的undefined确实是undefined而不是外面所更改的undefined,保证代码的正常运行。

举个简单的例子我们就能理解下:

    (function exmple(one,two){
        console.log(one);
        console.log(two);
    }("a"));

上面的代码执行后,会打印一个是“a”,另一个是undefined,

Paste_Image.png

因为我传实参是并没有给two这个形参传递实参,因此打印它时便是undefined。

**(二)、防冲突处理 **
上面我们提到了单独暴露出的$及jQuery这两个参数jQuery库也做了防冲突处理,那么它是怎么做防冲突处理的呢?请看下面:

(function(window, undefined) {
    var   ...
    _jQuery = window.jQuery,
    _$ = window.$,
//以上两行代码的意思是将window环境中的jQuery及$赋给了_jQuery及_$

....
//中间的jQuery代码

jQuery.extend({
.....
noConflict: function( deep ) {
        if ( window.$ === jQuery ) {
            window.$ = _$;
//以上语句进行判断全局下的$是否与 jQuery变量相等,如果相等,则把$还原回 jQuery运行之前的
//状态(通过存储在内部的变量_$赋给window.$),此时 jQuery的别名$失效
        }

        if ( deep && window.jQuery === jQuery ) {
            window.jQuery = _jQuery;
        }
//以上语句表示的意思是当开启深度冲突处理(deep为true)且jQuery变量和全局的jQuery相等时,
//将jQuery还原回jQuery运行之前的状态(通过存储在内部的变量_jQuery赋给window.jQuery),
//此时在全局中使用 jQuery库的 jQuery 失效

        return jQuery;
// 这里将返回jQuery 库的jQuery构造函数 new jQuery.fn.init()
    }
.....
})

}(window)

**(三)、无new构造对象 **
我们都知道我们在使用jQuery时,会首先使用$('xxx')再在其后面使用一些方法比如$('div').css("width","50px") 里的css。那么为什么在外界不需要使用new的方式构建jQuery对象呢?还有.text()、.append()、$.ajax()、$.trim()等等这些方法是怎么绑定的呢?接下来我们来分析下。
首先我们来分析下jQuery获取元素时为何不需要使用new的方式创建对象而直接使用$()或者jQuery()就可以构造对象。

(function(window, undefined) {
    var
    // ...
    jQuery = function(selector, context) {
        return new jQuery.fn.init(selector, context, rootjQuery);
 // 这里很巧妙,实例化方法 jQuery() 实际上是调用了jQuery.fn.init 也可称作jQuery 对象构造器
    },
 
  
    jQuery.fn = jQuery.prototype = {
        //赋给 jQuery原型里面的一些方法
        init: function(selector, context, rootjQuery) {
            // ...
        }
    }

    jQuery.fn.init.prototype = jQuery.fn;
//这一句也很巧妙:将 jQuery的原型赋给了 jQuery.fn.init的原型,这样新构造的 jQuery对象也可以
//使用jQuery的原型的一些方法与属性了
 
})(window);

其次我们来分析下上述第二个问题.text()、.append()、$.ajax()、$.trim()等是怎么挂载的。
a、我们先来看看jQuery中的.text()、.append()、.prepend()等实例方法

Paste_Image.png

我们可以看到.text()、.append()、.prepend()等实例方法都添加至jQuery原型上去了(通过extend 方法扩展);
b、接下来我们来看看jQuery中的$.each()、$.trim()等静态方法(也称工具方法)是怎么挂载的。

Paste_Image.png

通过查看源码我们发现,$.each()、$.trim()等静态方法都添加至jQuery本身上了,(也是通过extend 方法扩展的)这样我们就可以直接使用$.each('')、$.trim('')等方法了;

c、关于extend 方法是怎么实现的我们后面再详细做介绍;

**(四)、jQuery链式调用 **
我们都知道在jQuery中我们可以采用$('div').addClass("wrap").css("height","50px") 这样的方式书写也就是在选择一个元素后可以连续的在后面加方法,这其实就是链式调用。我们可以看看jQuery的源码:

Paste_Image.png

原来jQuery其实是通过返回this来实现链式调用的。以前我在这篇文章中也提到过链式调用,这里再贴出来那个简单的例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jQuery</title>
    <style type="text/css">
    </style>
</script>
</head>
<body>
    <script>
    var Dog=function (name,age){
        this.name=name;
        this.age=age;
    };
    Dog.prototype={
        getName:function(){
            console.log(this.name);
            return this
        },
        getAge:function(){
            console.log(this.age);
            return this
        }
    } ;
    Dogs=function(name,age){
        return new Dog(name,age);
    } ;    
    Dogs("goutou",3).getName().getAge();
    </script>

</body>
</html>
执行结果

**(五)、 钩子机制(hook) **
关于jQuery中的钩子机制可见这篇文章的钩子机制(hook)部分,写的很精彩。我就不在这赘言了。当然那篇博客里写的其他部分同样不错,推荐大家看看。

好了,今天先写到这里,后面有时间会继续浅析jQuery源码,jQuery里面的方法和思想确实令我们佩服并值得我们学习。
ps:其实还有多看看优秀库的代码,比如短小精悍的 underscore 也相当有帮助。

**本文版权归本人即简书笔名:该账户已被查封 所有,如需转载请注明出处。谢谢! *

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,576评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,515评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,017评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,626评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,625评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,255评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,825评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,729评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,271评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,363评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,498评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,183评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,867评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,338评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,458评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,906评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,507评论 2 359

推荐阅读更多精彩内容

  • 在线阅读 http://interview.poetries.top[http://interview.poetr...
    程序员poetry阅读 114,421评论 24 450
  • 1.JQuery 基础 改变web开发人员创造搞交互性界面的方式。设计者无需花费时间纠缠JS复杂的高级特性。 1....
    LaBaby_阅读 1,181评论 0 1
  • 1.JQuery 基础 改变web开发人员创造搞交互性界面的方式。设计者无需花费时间纠缠JS复杂的高级特性。 1....
    LaBaby_阅读 1,347评论 0 2
  • 掬一把时光 听风弄雨 品一壶花茶 浅尝轻啜 人,总是背负太多迷茫 一人远走 是因为想伪装坚强 一路独行 是因为怕识...
    艾弥儿阅读 501评论 8 19
  • 怀孕来到后期,因身体难以负荷工作强度,提前一月请假,休息在家时间已经过半,这“偷得浮生半月闲”里,每天的生活...
    葱芒小护阅读 452评论 0 0