jquery源碼之總體架構分析

jquery的總體代碼架構簡化以下:jquery

(function( window, undefined ) {
    //...定義各類變量
    jQuery = function( selector, context ) {
        return new jQuery.fn.init( selector, context, rootjQuery );
    },
    jQuery.fn = jQuery.prototype = {
        constructor: jQuery,
        init: function( selector, context, rootjQuery ) {},
        ...
    };
    jQuery.fn.init.prototype = jQuery.fn;
    if ( typeof window === "object" && typeof window.document === "object" ) {
        window.jQuery = window.$ = jQuery;
    }
})( window );

這裏有幾點須要整明白的:
一、使用一個閉包定義jquery,建立一個私有空間,這樣內外部的命名空間就不會相互干擾了。爲了在外部可以使用jquery,將jquery($)提高到window做用域下,即:chrome

window.jQuery = window.$ = jQuery;

二、爲何要將window做爲參數傳入:
有兩個好處,一是便於代碼壓縮,jquery每一個版本都有壓縮版,如將傳入的window參數命名爲w,則可減小大量的代碼量;二是將window全局變量變成局部變量,可加快訪問速度。瀏覽器

三、爲何要增長undefined參數:
undefined在某些瀏覽器(如chrome、ie等)是能夠被修改的,如:閉包

undefined = "hello";

爲了保證在jQuery內部,使用到的undefined真的是undefined而沒有被修改過,將它做爲參數傳入。
ok,上面幾點都比較好理解,下面開始分析jquery的構建方式。
jQuery至關於一個類,在jquery中,咱們使用$()或jQuery()來獲得jquery實例,按此思路定義jQuery類以下:架構

var jQuery = function() {
    return new jQuery();
}

啊噢,死循環了~
想拿到實例,即this,原方法拿不到,就去原型那裏拿咯:this

var jQuery = function() {
    return jQuery.prototype.init();
}
jQuery.prototype = {
    init:function() {
        return this;
    }
}

但這樣仍是會有問題,由於這樣至關於單例了,建立出來的對象相互共享做用域,必然致使不少問題,如prototype

var jQuery = function() {
    return jQuery.prototype.init();
}
jQuery.prototype = {
    init:function() {
        return this;
    },
    age:18
}
var jq1 = new jQuery();
var jq2 = new jQuery();
jq1.age = 20;
console.log(jq1.age); //20
console.log(jq2.age); //20

因此須要讓他們的做用域分離,互不干擾,故每次建立新對象便可解決:code

var jQuery = function() {
    return new jQuery.prototype.init();
}
jQuery.prototype = {
    init:function() {
        return this;
    }
}

可是這樣仍然是有問題的,如:對象

var jQuery = function() {
    return new jQuery.prototype.init();
}
jQuery.prototype = {
    init:function() {
        return this;
    },
    age:18
}
var jq = new jQuery();
console.log(jq.age); //undefined

緣由是這裏init和外部的jquery.prototype分離了,init對象中並無age屬性。
改改改:作用域

var jQuery = function() {
    return new jQuery.prototype.init();
}
jQuery.prototype = {
    init:function() {
        return this;
    },
    age:18
}
jQuery.prototype.init.prototype = jQuery.prototype;

好了,到此爲止基本沒啥問題了,jQuery也是這樣實現的,只是多了個jQuery.fn做爲jQuery.prototype的引用而已,沒多少特別意義。

相關文章
相關標籤/搜索