成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

讀jQuery源碼之整體框架分析

開發(fā) 前端
讀一個開源框架,大家最想學到的就是設計的思想和實現的技巧。最近讀jQuery源碼,記下我對大師作品的理解和心得,跟大家分享,權當拋磚引玉。

讀一個開源框架,大家最想學到的就是設計的思想和實現的技巧。最近讀jQuery源碼,記下我對大師作品的理解和心得,跟大家分享,權當拋磚引玉。

先附上jQuery的代碼結構。

JS代碼

  1. (function(){  
  2.     //jQuery變量定義  
  3.     var jQuery  = function(){...};  
  4.     //jQuery原型定義(包含核心方法)                
  5.     jQuery.fn = jQuery.prototype = {...};  
  6.     //看上去很奇怪吧? 非常巧妙的設計,后面詳細介紹  
  7.     jQuery.fn.init.prototype = jQuery.fn;  
  8.     //提供jQuery靜態(tài)方法與對象方法的擴展函數  
  9.     jQuery.extend = jQuery.fn.extend = function(){...};   
  10.     //后面依次有多個對jQuery靜態(tài)方法的擴展  
  11.     jQuery.extend({...});  
  12.     //后面依次有多個對jQuery對象方法的擴展  
  13.     jQuery.fn.extend({...});  
  14.     jQuery.support = (function() {...})();  
  15.     //提供統(tǒng)一時間管理,jQuery內部使用,并不對外開放  
  16.     jQuery.event = {...};  
  17.     //Event類似于Java的POJO類.傳遞事件的對象  
  18.     jQuery.Event = function( src, props ) {...};   
  19.     //Sizzle選擇器,一個框架,可獨立使用。  
  20.     (function(){  
  21.         ...  
  22.         jQuery.find = Sizzle;  
  23.         ...  
  24.     })();  
  25.     ...  
  26.     //將定義的jQuery定義為全局變量  
  27.     window.jQuery = window.$ = jQuery;  
  28.     ...  
  29. })(); 

在結構上非常的清晰,定義一個jQuery對象,對jQuery對象進行擴展,賦給window,變成全局變量。就以下幾點做介紹:

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

2). $("...")形式調用返回 jQuery.fn.init對象。

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

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

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

二. $("...")形式調用返回 jQuery.fn.init對象。

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

Js代碼

  1. var jQuery = function( selector, context ) {  
  2.     // The jQuery object is actually just the init constructor 'enhanced'  
  3.     return new jQuery.fn.init( selector, context, rootjQuery );  
  4. }  
  5. 和  
  6. jQuery.fn.init.prototype = jQuery.fn; 

看懂這段我們先看看jQuery的使用。jQuery采用鏈式調用(如:$("#id").data("xxx")),這樣就知道$("#id")返回的是一個jQuery對象。但是調用的方式是函數調用。這個問題就成為了:以函數的方式調用返回jQuery對象,并且構造函數是init。現在就圍繞解決這個問題展開:

首先想到的是在函數式調用的時候返回一個jQuery對象。

  1. var jQuery = function( selector, context ) {  
  2.     return new jQuery( selector, context);  

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

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

JS代碼

  1. var jQuery = function( selector, context ) {  
  2.     return new A( selector, context);  
  3. }  
  4.  
  5. var A = function(){  
  6.     if(this.init) {  
  7.         this.init();  
  8.     }  
  9. };  
  10. A.prototype = jQuery.prototype; 

這樣就解決了上面的問題,因為jQuery和A擁有同一個原型,所以生成的對象都擁有相同的方法。但是還是感覺A定義的有些多余,是不是?

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

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

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

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

  1. var jQuery = function( selector, context ) {  
  2.     //如果以$("#id") 方式調用this就不是jQuery.這樣返回jQuery對象  
  3.     if(!(this instanceof jQuery)) {  
  4.         return new jQuery(selector, context);  
  5.     }  
  6.     if(this.init) {  
  7.         this.init();  
  8.     }  
  9. }  
  10. //這行就可以注釋了  
  11. //jQuery.fn.init.prototype = jQuery.fn; 

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

三. 框架里最看到的 extend 函數

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

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

1)$.Ajax(...);

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

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

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

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

第二種調用我成為對象調用,因為.data()方法是定義在原型中的,只有new個對象才能調用的,所以成為對象方法。

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

原文鏈接:http://www.iteye.com/topic/1126505

【編輯推薦】

  1. 淺談管理系統(tǒng)操作日志設計(附操作日志類)
  2. Winform開發(fā)框架之系統(tǒng)登錄實現
  3. JavaScript項目優(yōu)化總結
  4. 項目模塊開發(fā)——切dvd庫
  5. 如何掌握程序語言
責任編輯:張偉 來源: lcyangily的博客
相關推薦

2016-11-25 13:14:50

Flume架構源碼

2022-07-19 20:04:31

NAPI模塊鴻蒙

2012-11-06 11:07:59

jQueryJSjQuery框架

2017-07-17 11:52:54

jQuery源碼分析前端框架類庫

2011-05-26 10:05:48

MongoDB

2013-09-16 10:40:44

Sizzle

2012-09-20 10:07:29

Nginx源碼分析Web服務器

2023-02-26 08:42:10

源碼demouseEffect

2021-03-23 09:17:58

SpringMVCHttpServletJavaEE

2021-07-06 09:29:38

Cobar源碼AST

2024-06-13 07:55:19

2011-05-26 16:18:51

Mongodb

2016-03-23 11:05:58

Socket開發(fā)框架分析

2019-02-21 23:36:09

源碼框架讀源碼

2020-07-28 08:54:39

內核通信Netlink

2021-09-05 07:35:58

lifecycleAndroid組件原理

2015-09-11 09:17:55

JavaJava HashMa

2021-09-16 15:08:08

鴻蒙HarmonyOS應用

2017-01-12 14:52:03

JVMFinalRefere源碼

2009-07-08 13:22:30

JDK源碼分析Set
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 九九热精品视频 | 2020天天操| 天天做日日做 | 最新中文在线视频 | 隔壁老王国产在线精品 | 黄免费在线 | 欧美精品成人影院 | 色爱综合网| 91免费在线视频 | 日韩精品在线观看免费 | 久久久精 | 成人午夜精品 | 久久久久91 | 国产伦精品一区二区三区视频金莲 | 九色91视频 | 欧美激情综合五月色丁香小说 | 一区二区日本 | 成年人的视频免费观看 | 91九色视频 | 雨宫琴音一区二区在线 | 中文字幕免费视频 | 免费久久精品视频 | 国产精品午夜电影 | 成人精品久久 | 中文字幕第九页 | 麻豆国产一区二区三区四区 | 成人免费一区二区三区牛牛 | 国产特一级黄色片 | 国产激情在线 | 国产在线资源 | 97起碰 | 免费在线一区二区三区 | 一区二区久久精品 | 日韩欧美在线视频一区 | 国产精品视频一区二区三区 | 夜夜爽99久久国产综合精品女不卡 | 亚洲一区在线日韩在线深爱 | 午夜伦4480yy私人影院 | 日韩视频高清 | 天天综合久久 | 欧美日一区二区 |