jQuery源碼分析,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的id選擇器

一直在使用jQuery蛇数,也一直想更深層次的學(xué)習(xí)jQuery挪钓,下面就從jQuery的結(jié)構(gòu)說(shuō)起。并通過一個(gè)小例子耳舅,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的選擇器獲取文本內(nèi)容的功能碌上。

  • 在jQuery源碼,你會(huì)看到下面的結(jié)構(gòu):
(function(window,undefined){
    var jQuery = ;
    window.jQuery = $.jQuery = jQuery;
})(window);

這個(gè)結(jié)構(gòu)代表創(chuàng)建一個(gè)匿名函數(shù)并且立即執(zhí)行浦徊。通過這個(gè)匿名函數(shù)馏予,創(chuàng)建了一個(gè)“私有”的命名空間,可以防止變量沖突污染盔性。

由于undefined可以被重寫霞丧,被修改為其他的值,因此將undefined作為參數(shù)傳入冕香,可以保證undefined確實(shí)是未定義蛹尝。
  • jQuery對(duì)象構(gòu)造函數(shù)
//構(gòu)造jQuery對(duì)象
var jQuery = function(selector,context){
    return new jQuery.fn.init(selector,context,rootjQuery);
}

jQuery對(duì)象不是通過 new jQuery 創(chuàng)建的,而是通過 new jQuery.fn.init 創(chuàng)建的悉尾。定義了jQuery對(duì)象突那,實(shí)際就是一個(gè)函數(shù),這個(gè)函數(shù)返回的是new jQuery.fn.init( selector, context, rootjQuery );构眯,所以jQuery對(duì)象就是*** jQuery.fn.init*** 實(shí)例愕难。

  • jQuery原型
    jQuery的原型就是jQuery.fn,所以在fn上添加的方法可以在任何jQuery對(duì)象中直接調(diào)用惫霸。
jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype
這里會(huì)有點(diǎn)繞猫缭,我也是參考了別人的網(wǎng)站上寫的。
所有掛載到j(luò)Query.fn的方法壹店,相當(dāng)于掛載到了jQuery.prototype猜丹,
即掛載到了jQuery 函數(shù)上(一開始的 jQuery = function( selector, context ) ),
但是最后都相當(dāng)于掛載到了jQuery.fn.init.prototype硅卢,
即相當(dāng)于掛載到了一開始的jQuery 函數(shù)返回的對(duì)象上射窒,即掛載到了我們最終使用的jQuery對(duì)象上妖混。
  • 下面我們就來(lái)看jQuery.fn.init
    jQuery.fn.init的功能是對(duì)傳進(jìn)來(lái)的selector參數(shù)進(jìn)行分析,進(jìn)行各種不同的處理轮洋,然后生成jQuery對(duì)象。
這個(gè)init函數(shù)就是原型抬旺,jQuery函數(shù)構(gòu)造函數(shù)弊予。
這個(gè)函數(shù)接收三個(gè)參數(shù),分別是選擇器开财,上下文和root汉柒,
這個(gè)root在return new jQuery.fn.init( selector, context, rootjQuery );已經(jīng)定死了,
就是rootjQuery 就是 document對(duì)象,
所以實(shí)際上只有兩個(gè)參數(shù)可用责鳍,就是selector和context碾褂。
pic1.png
根據(jù)selector和context參數(shù)的不同,分情況處理历葛,依次處理了如下幾種情況  
 1, selector為空正塌,則直接返回空的jquery對(duì)象  
 2,如果selector是字符串恤溶,分如下幾種情況  
     2.1, selector是 '<xxx>'類型的乓诽,則直接創(chuàng)建html片段,
          同時(shí)如果context是plainObject則把其中的屬性全部賦值給創(chuàng)建出來(lái)的html片段  
     2.2,如果selector是一個(gè)id選擇器咒程,則直接調(diào)用getElementById來(lái)選擇元素  
     2.3, 如果context為空鸠天,調(diào)用rootjQuery.find(selector),
          如果context是jquery對(duì)象,則直接調(diào)用context.find(selector)  
     2.4帐姻,到這里稠集,說(shuō)明context也是一個(gè)選擇器,則直接調(diào)用$(context).find(selector)  
 3, 如果selector是一個(gè)DOMElement,則直接使用,不用去找了  
 4, 如果selector是一個(gè)函數(shù)头朱,則在documentready時(shí)調(diào)用此函數(shù)  
 5卓囚,兼容另一種寫法,即直接傳一個(gè)對(duì)象 {selector:xxx, context:xxx}

到此基本的知識(shí)點(diǎn)就講到這里败匹,我們來(lái)看jQuery源碼的結(jié)構(gòu)

(function( window, undefined) {
   
    var jQuery = (function() {
       // 構(gòu)建jQuery對(duì)象
       var jQuery = function( selector, context ) {
           return new jQuery.fn.init( selector, context, rootjQuery );
       }
   
       // jQuery對(duì)象原型
       jQuery.fn = jQuery.prototype = {
           constructor: jQuery,
           init:  function ( selector, context, rootjQuery ) {
           }
       };
   
       // 合并內(nèi)容到第一個(gè)參數(shù)中,后續(xù)大部分功能都通過該函數(shù)擴(kuò)展
       // 通過jQuery.fn.extend擴(kuò)展的函數(shù),大部分都會(huì)調(diào)用通過jQuery.extend擴(kuò)展的同名函數(shù)
       jQuery.extend = jQuery.fn.extend = **function**() {};
      
       // 在jQuery上擴(kuò)展靜態(tài)方法
       jQuery.extend({
           
       });
 
        // 到這里鳖宾,jQuery對(duì)象構(gòu)造完成,后邊的代碼都是對(duì)jQuery或jQuery對(duì)象的擴(kuò)展
       return jQuery;
   
    })();
   
    window.jQuery = window.$ = jQuery;
})(window);

下面是模擬jQuery實(shí)現(xiàn)簡(jiǎn)單的獲取元素內(nèi)容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo</title>
</head>
<body>
    <div id="testText">
        測(cè)試文本
    </div>
</body>
<script>
    (function(window,undefined){
        var rootjQuery = window.document;
        var jQuery = (function(){
            var jQuery = function(selector,context){
                return new jQuery.fn.init( selector, context, rootjQuery );
            }

            jQuery.fn = jQuery.prototype ={
                construct: jQuery,
                init: function( selector, context, rootjQuery ){
                    var that = this;
                    that.ele = null;
                    that.value = '';
                    if(selector.charAt(0) === '#'){
                        console.log(selector);
                        that.ele = document.getElementById(selector.slice(1));
                    }
                    that.getValue = function(){
                        that.value = that.ele ? that.ele.innerHTML : 'No value';
                        return that;
                    };
                    that.showValue = function(){
                        return that.value;
                    };
                }
            };

            jQuery.fn.init.prototype = jQuery.fn;
            return jQuery;
        })();

        window.jQuery = window.$ = jQuery;
    })(window);


    //測(cè)試
    var testText = $('#testText').getValue().showValue(); //
    alert(testText);
</script>
</html>

這里只實(shí)現(xiàn)了根據(jù)id來(lái)查找到具體的元素逆航,其他拓展的方法鼎文,如根據(jù)類名來(lái)實(shí)現(xiàn)查找 都可以寫在init函數(shù)中。

注意:var rootjQuery = window.document;這句話不要省略因俐。

參考文章:1 2

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拇惋,一起剝皮案震驚了整個(gè)濱河市周偎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌撑帖,老刑警劉巖蓉坎,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異胡嘿,居然都是意外死亡蛉艾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門衷敌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)勿侯,“玉大人,你說(shuō)我怎么就攤上這事缴罗≈觯” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵面氓,是天一觀的道長(zhǎng)兵钮。 經(jīng)常有香客問我,道長(zhǎng)侧但,這世上最難降的妖魔是什么矢空? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮禀横,結(jié)果婚禮上屁药,老公的妹妹穿的比我還像新娘。我一直安慰自己柏锄,他們只是感情好酿箭,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著趾娃,像睡著了一般缭嫡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抬闷,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天妇蛀,我揣著相機(jī)與錄音,去河邊找鬼笤成。 笑死评架,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的炕泳。 我是一名探鬼主播纵诞,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼培遵!你這毒婦竟也來(lái)了浙芙?” 一聲冷哼從身側(cè)響起登刺,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嗡呼,沒想到半個(gè)月后纸俭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡南窗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年掉蔬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矾瘾。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖箭启,靈堂內(nèi)的尸體忽然破棺而出壕翩,到底是詐尸還是另有隱情,我是刑警寧澤傅寡,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布放妈,位于F島的核電站,受9級(jí)特大地震影響荐操,放射性物質(zhì)發(fā)生泄漏芜抒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一托启、第九天 我趴在偏房一處隱蔽的房頂上張望宅倒。 院中可真熱鬧,春花似錦屯耸、人聲如沸拐迁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)线召。三九已至,卻和暖如春多矮,著一層夾襖步出監(jiān)牢的瞬間缓淹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工塔逃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留讯壶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓患雏,卻偏偏與公主長(zhǎng)得像鹏溯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子淹仑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 一般我們?nèi)懸粋€(gè)框架丙挽,會(huì)采用什么樣的設(shè)計(jì)呢肺孵?比如設(shè)計(jì)一個(gè)jQuery框架,一般我們會(huì)創(chuàng)建一個(gè)函數(shù)對(duì)象 functi...
    Michael_bdb5閱讀 643評(píng)論 0 2
  • 前言 本來(lái)只是一個(gè)自己學(xué)習(xí)jQuery筆記的簡(jiǎn)單分享颜阐,沒想到獲得這么多人賞識(shí)平窘。我自己也是傻呵呵的一臉迷茫,感覺到受...
    車大棒閱讀 656評(píng)論 3 11
  • 請(qǐng)參看我github中的wiki凳怨,不定期更新瑰艘。https://github.com/ivonzhang/Front...
    zhangivon閱讀 7,114評(píng)論 2 19
  • 題外話: 看源碼的工具:lambda-view【基于nodejs環(huán)境】。我感覺之所以好用是因?yàn)榭梢灾苯釉跒g...
    狂瀾1991閱讀 488評(píng)論 0 2
  • 看到題目肤舞,讀完文章紫新,感覺自己心里還是有話要說(shuō)。 作為一名已婚人士來(lái)說(shuō)起這個(gè)話題李剖,心中莫名有些興奮芒率,或許是覺得終于有...
    童Vs源閱讀 437評(píng)論 0 1