如何進(jìn)行jQuery源碼的整體框架分析

這篇文章將為大家詳細(xì)講解有關(guān)如何進(jìn)行jQuery源碼的整體框架分析,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

十載的花垣網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整花垣建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)公司從事“花垣網(wǎng)站設(shè)計(jì)”,“花垣網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

先附上jQuery的代碼結(jié)構(gòu)。

JS代碼

(function(){      //jQuery變量定義      var jQuery  = function(){...};      //jQuery原型定義(包含核心方法)                    jQuery.fn = jQuery.prototype = {...};      //看上去很奇怪吧? 非常巧妙的設(shè)計(jì),后面詳細(xì)介紹      jQuery.fn.init.prototype = jQuery.fn;      //提供jQuery靜態(tài)方法與對(duì)象方法的擴(kuò)展函數(shù)      jQuery.extend = jQuery.fn.extend = function(){...};       //后面依次有多個(gè)對(duì)jQuery靜態(tài)方法的擴(kuò)展      jQuery.extend({...});      //后面依次有多個(gè)對(duì)jQuery對(duì)象方法的擴(kuò)展      jQuery.fn.extend({...});      jQuery.support = (function() {...})();      //提供統(tǒng)一時(shí)間管理,jQuery內(nèi)部使用,并不對(duì)外開放      jQuery.event = {...};      //Event類似于Java的POJO類.傳遞事件的對(duì)象      jQuery.Event = function( src, props ) {...};       //Sizzle選擇器,一個(gè)框架,可獨(dú)立使用。      (function(){          ...          jQuery.find = Sizzle;          ...      })();      ...      //將定義的jQuery定義為全局變量      window.jQuery = window.$ = jQuery;      ...  })();

在結(jié)構(gòu)上非常的清晰,定義一個(gè)jQuery對(duì)象,對(duì)jQuery對(duì)象進(jìn)行擴(kuò)展,賦給window,變成全局變量。就以下幾點(diǎn)做介紹:

1). 自執(zhí)行的匿名函數(shù)。

2). $("...")形式調(diào)用返回 jQuery.fn.init對(duì)象。

3). 框架里最常見的 extend 函數(shù)。

一. 自執(zhí)行匿名函數(shù)。

對(duì)javascript有一定基礎(chǔ)的都應(yīng)該知道自執(zhí)行匿名函數(shù)的好處。js是函數(shù)作用域。在函數(shù)里定義的變量都是局部變量,這樣就很好的避免了過多的全局變量(jQuery僅僅2個(gè)全局變量jQuery和$)。由于閉包屬性,雖然函數(shù)自執(zhí)行結(jié)束了,但自執(zhí)行函數(shù)里面定義的局部函數(shù)和變量還是能夠被定義成全局變量的jQuery和$所引用到,類似于Java的私有變量。好處可見一斑。

二. $("...")形式調(diào)用返回 jQuery.fn.init對(duì)象。

這是我剛看源碼的時(shí)候最不理解的地方。

Js代碼

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.init.prototype = jQuery.fn;

看懂這段我們先看看jQuery的使用。jQuery采用鏈?zhǔn)秸{(diào)用(如:$("#id").data("xxx")),這樣就知道$("#id")返回的是一個(gè)jQuery對(duì)象。但是調(diào)用的方式是函數(shù)調(diào)用。這個(gè)問題就成為了:以函數(shù)的方式調(diào)用返回jQuery對(duì)象,并且構(gòu)造函數(shù)是init?,F(xiàn)在就圍繞解決這個(gè)問題展開:

首先想到的是在函數(shù)式調(diào)用的時(shí)候返回一個(gè)jQuery對(duì)象。

var jQuery = function( selector, context ) {      return new jQuery( selector, context);  }

兄弟,你確定這樣? 明眼人一看就知道嚴(yán)重的問題所在,死遞歸!

既然不能調(diào)用本身,那我們想到另一種辦法:再定義一個(gè)函數(shù)A,A的原型與jQuery的原型一樣,那A的對(duì)象與jQuery生成的對(duì)象就是一模一樣了(javascript是原型繼承),而且將A的constructor定義為jQuery,上面的問題不是迎刃而解么?

JS代碼

var jQuery = function( selector, context ) {      return new A( selector, context);  }   var A = function(){      if(this.init) {          this.init();      }  };  A.prototype = jQuery.prototype;

這樣就解決了上面的問題,因?yàn)閖Query和A擁有同一個(gè)原型,所以生成的對(duì)象都擁有相同的方法。但是還是感覺A定義的有些多余,是不是?

既然定義A就為了返回A的對(duì)象,那init函數(shù)也能生成對(duì)象(以為js中沒有類,定義的函數(shù)可以當(dāng)函數(shù)執(zhí)行,也能new成對(duì)象)。既然用init的話,那樣init函數(shù)會(huì)自動(dòng)執(zhí)行,也不用再調(diào)用,豈不是更方便!所以就看到了我們之前看到的代碼。

這里可能還有個(gè)fn解釋下,其實(shí)這個(gè)fn沒有什么特殊意思,只是jQuery.prototype的引用,jQuery支持自己擴(kuò)展屬性,這個(gè)對(duì)外提供了一個(gè)接口,jQuery.fn.extend()來對(duì)對(duì)象增加方法,比使用jQuery.prototype.extend()更好。封裝想,字面就能看懂是對(duì)函數(shù)擴(kuò)展,而不是看上去直接修改prototype.友好的用戶接口。

相對(duì)于文字,圖形化更加直觀,對(duì)上面的引用來引用去畫了個(gè)圖,更好的理解:

如何進(jìn)行jQuery源碼的整體框架分析

其實(shí)在使用返回 new jQuery.fn.init( selector, context, rootjQuery ) 對(duì)象方式,我還有另一種實(shí)現(xiàn):

var jQuery = function( selector, context ) {      //如果以$("#id") 方式調(diào)用this就不是jQuery.這樣返回jQuery對(duì)象      if(!(this instanceof jQuery)) {          return new jQuery(selector, context);      }      if(this.init) {          this.init();      }  }  //這行就可以注釋了  //jQuery.fn.init.prototype = jQuery.fn;

這種經(jīng)過測(cè)試時(shí)可以的,不知道還有沒有其他的隱蔽問題,暫時(shí)沒發(fā)現(xiàn),也算是一種實(shí)現(xiàn)吧。供大家參考。

三. 框架里最看到的 extend 函數(shù)

在后面的段落中有大段大段的 jQuery.extend({...}) 和 jQuery.fn.extend({...}) 代碼。這里先解釋下這個(gè)的作用和不同。

extend 在java中是繼承,在我之前寫的一篇 <簡(jiǎn)單實(shí)現(xiàn)Javascrip繼承> 文章不同,也都是用了extend關(guān)鍵字。那些我們都說叫繼承,而這里我更加喜歡叫擴(kuò)展。為什么呢? 繼承是產(chǎn)生了新的類,而這里沒有,這里的2個(gè)函數(shù)***個(gè)是擴(kuò)展jQuery的靜態(tài)方法,而第二個(gè)是用戶自己擴(kuò)展對(duì)象的方法。靜態(tài)方法?對(duì)象方法?這里我來做個(gè)解釋,在jQuery中有2中調(diào)用形式:

1)$.Ajax(...);

2)$("#id").data("xxx");

***種調(diào)用我稱為靜態(tài)調(diào)用,就類似于Java的靜態(tài)方法一樣,不用生成對(duì)象,而是類級(jí)函數(shù)。這里的$就相當(dāng)于命名空間一樣。我們知道在以往js的編程中,如果有命名空間我們都這樣:

var ns = {};  ns.Ajax = function(){...};

那為什么這里不是對(duì)象,而是函數(shù)做一個(gè)命名空間呢? 其實(shí)在js中一切都是對(duì)象!包括函數(shù)也是對(duì)象(說Java一切都是對(duì)象,我覺得其實(shí)這句話形容js更加貼切)。

第二種調(diào)用我成為對(duì)象調(diào)用,因?yàn)?data()方法是定義在原型中的,只有new個(gè)對(duì)象才能調(diào)用的,所以成為對(duì)象方法。

我們看代碼jQuery.extend = jQuery.fn.extend = function(){...}; 這個(gè)是連等,也就是2個(gè)指向同一個(gè)函數(shù),怎么會(huì)實(shí)現(xiàn)不同的功能呢?這就是this 的功能了。jQuery.extend 調(diào)用的時(shí)候,this是指向jQuery對(duì)象的(jQuery是函數(shù),也是對(duì)象!),所以這里擴(kuò)展在jQuery上。 而jQuery.fn.extend 調(diào)用的時(shí)候,this指向fn對(duì)象,而上圖中科院看到,jQuery.fn 和jQuery.prototype指向同一對(duì)象,擴(kuò)展fn就是擴(kuò)展jQuery.prototype原型對(duì)象。這里增加的是原型方法,也就是對(duì)象方法了。所以jQuery的api中提供了以上2中擴(kuò)展函數(shù)。

關(guān)于如何進(jìn)行jQuery源碼的整體框架分析就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

網(wǎng)頁題目:如何進(jìn)行jQuery源碼的整體框架分析
文章路徑:http://muchs.cn/article6/ihsdig.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)、網(wǎng)站改版服務(wù)器托管、建站公司、用戶體驗(yàn)Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)