jQuery源碼-核心源碼結構


從github直接拷貝過來,排版不是很友好,可點擊這里查看github上的文章

前端的童鞋對jQuery絕對不會陌生,有不少剛入門的筒子,在不知JS為何物的時候,就已經在用jQuery了。這也應該歸功於前端惡劣的生存環境:各自為政的瀏覽器廠商,依舊嚴峻的兼容性問題,並不好用的原生API。。。

使用jQuery的理由有很多,喜歡它的理由也很多,優雅的接口,豐富的插件,完善的文檔等。作為一名有進取心的前端攻城獅,大家心理或多或少都有一個框架夢,總用它人寫的庫,內心總歸有些那么不是滋味。

那好吧,干脆自己寫一個,“師夷長技以自強”嘛,於是熱火朝天地開工,一個又一個小JQ就這樣橫空出世。再精心挑選上好的測試用例證明自己的庫比其他庫更牛逼,當然,jQuery基本都在對比之列。

此處省略三千字。。下面開始進入jQuery源碼分析之路

jQuery是什么

好吧,這里的jQuery指的並不是“jQuery庫”,而是jQuery這個對象。首先用你習慣使用的編輯器打開jQuery-1.9.1.js,最好能夠支持代碼高亮和智能折疊。好家伙,源碼加注釋共9500++行,怪嚇人的。沒錯,這是每個有志學習jQuery源碼的童鞋需要過的第一道坎。其實,完全沒有必要害怕,將多余的噪音去掉,其實jQuery就是下面幾行代碼而已:

(function( window, undefined ) {
    var jQuery = function( selector, context ) {
        // The jQuery object is actually just the init constructor 'enhanced'
        return new jQuery.fn.init( selector, context, rootjQuery );
    };
    window.jQuery = window.$ = jQuery;
})( window );

我們更為常用的美元符號$,其實就是jQuery的同名對象,而jQuery是個方法,它的作用是返回一個jQuery對象,更確切地來說,是jQuery.fn.init對象。至於為什么會返回jQuery.fn.init對象,可以小小參考下之前寫的另一篇文章【jquery學習筆記】美元背后的一點小技巧

 

從一行代碼說jQuery的核心源碼結構

有下面這么一行代碼

$('#casper').addClass('handsome‘),

這行代碼的作用不用多說:給ID為casper的dom節點添加一個名為handsome的class。很簡單的一句代碼,拆成兩部分來看:

  • $('#casper') 返回一個jQuery對象,該對象的屬性’0‘包含了選中的dom節點=> $('#casper')[0] === document.getElementById('casper')
  • .addClass('handsome') 給選中的dom節點添加handsome類,addClass為jQuery的prototype方法

於是我們把之前的那個簡陋的骨架再豐滿下,整個jQuery的骨架就基本出來了,里面的代碼關鍵點在**源碼骨架**后面會逐個進行講解

 

源碼骨架

(function( window, undefined ) {
var
    jQuery = function( selector, context ) {
        // The jQuery object is actually just the init constructor 'enhanced'
        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;

    //extend方法,用來擴展jQuery,或jQuery.fn
    jQuery.extend = jQuery.fn.extend = function() {
        //...
    };

    jQuery.fn.extend({
        addClass: function( value ) {
            //...
            return this;    //返回this,鏈式調用的秘密
        }
    });

    window.jQuery = window.$ = jQuery;

})( window );

 

return new jQuery.fn.init( selector, context, rootjQuery );

$('#casper')跟new $('#casper')是一樣的。個人覺得這里設計的原因,一個減少寫一堆new的麻煩,同時也可以避免開發者不小心遺漏了new導致的詭異bug。當然,不好的地方是,代碼有點繞,這也算是jQuery源碼的其中一個特點。

jQuery.fn = jQuery.prototype

沒什么好講,jQuery.prototype為jQuery的原型方法,這里用jQuery.fn來代替jQuery.prototype,只是為了少寫幾個字符,平常寫插件時就是在這東東上面做修改

jQuery.fn.init.prototype = jQuery.fn

很好很繞的一個語句,上面說了$(’#casper‘)返回的其實是個jQuery.fn.init對象。所以,這里的作用,是讓jQuery.fn上的方法都成為jQuery.fn.init對象的原型方法。 這個語句應該讓很多剛接觸jQuery源碼的人感到困惑,包括我(=_=),可以試jQuery.fn.init.prototype.init.prototype.init...,如果你願意可以一直寫下去。

addClass: function( value ) {...

下面這段代碼很短很關鍵,別看它很簡單,jQuery眾多強大的接口就是這樣通過jQuery.fn.extend一個一個擴展出來的,不贅述

    jQuery.fn.extend({
        addClass: function( value ) {

 

寫在后面

本文對jQuery源碼核心結構進行了粗略的介紹,當然jQuery實際的源碼要比這個復雜得多,但只要掌握了上面的要點,后續的分析就會輕松很多。jQuery源碼之所以比較難看懂,是因為里面有許多為了解決糟糕的瀏覽器兼容性問題而引進的hack。

萬事開頭難,這是筆者jQuery源碼解析的開篇之作,網絡上這類的文章很多,而且有些寫的很不錯,這里寫作的原因,一來總結,二來備忘。

未完待續。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM