日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【jQuery源码】整体架构

發布時間:2025/5/22 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【jQuery源码】整体架构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  jQuery源碼可以精簡為以下內容:

  方框上面的代碼根據Jq注釋我們可以知道是對AMD規范的支持。

  jQuery整體上被包裹在一個匿名函數中,這個匿名函數再作為另一個匿名函數的參數被傳入,形參factory。

?

一、自調用函數

  整個部分被自調用函數包裹,通過定義一個匿名函數,創建了一個“私有”的命名空間,該命名空間的變量和方法,不會破壞全局的命名空間。

  自調用函數中的第一個參數相當于window,通過傳入window變量,使得window由全局變量變為局部變量,當在jQuery代碼塊中訪問window時,不需要將作用域鏈回退到頂層作用域,這樣可以更快的訪問window;這還不是關鍵所在,更重要的是,將window作為參數傳入,可以在壓縮代碼時進行優化。

  第二個參數為包裹jQuery的匿名函數,在匿名參數中被調用——factory()。

?

二、jQuery的無new構建

  jQuery框架的核心就是從HTML文檔中匹配元素并對其執行操作、

  例如:

$().find().css() $().hide().html('....').hide().

  從上面的寫法上至少可以發現2個問題

  1. jQuery對象的構建方式

  2 .jQuery方法的調用方式

?

分析一:jQuery的無new構建

  JavaScript是函數式語言,函數可以實現類,類就是面向對象編程中最基本的概念

var aQuery = function(selector, context) {//構造函數 } aQuery.prototype = {//原型name:function(){},age:function(){} }var a = new aQuery();a.name();

  這是常規的使用方法,顯而易見jQuery不是這樣玩的

  jQuery沒有使用new運行符將jQuery顯示的實例化,還是直接調用其函數

  按照jQuery的抒寫方式

$().ready() $().noConflict()

  要實現這樣,那么jQuery就要看成一個類,那么$()應該是返回類的實例才對

  所以把代碼改一下:

var aQuery = function(selector, context) {return new aQuery(); } aQuery.prototype = {name:function(){},age:function(){} }

  通過new?aQuery(),雖然返回的是一個實例,但是也能看出很明顯的問題,死循環了!

?


那么如何返回一個正確的實例?

  在javascript中實例this只跟原型有關系

  那么可以把jQuery類當作一個工廠方法來創建實例,把這個方法放到jQuery.prototye原型中

var aQuery = function(selector, context) {return aQuery.prototype.init(); } aQuery.prototype = {init:function(){return this;}name:function(){},age:function(){} }

  當執行aQuery() 返回的實例:

  很明顯aQuery()返回的是aQuery類的實例,那么在init中的this其實也是指向的aQuery類的實例

  問題來了init的this指向的是aQuery類,如果把init函數也當作一個構造器,那么內部的this要如何處理?

var aQuery = function(selector, context) {return aQuery.prototype.init(); } aQuery.prototype = {init: function() {this.age = 18return this;},name: function() {},age: 20 }aQuery().age //18

  這樣的情況下就出錯了,因為this只是指向aQuery類的,所以需要設計出獨立的作用域才行

?


jQuery框架分隔作用域的處理

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

  很明顯通過實例init函數,每次都構建新的init實例對象,來分隔this,避免交互混淆

  那么既然都不是同一個對象那么肯定又出現一個新的問題

例如:

var aQuery = function(selector, context) {return new aQuery.prototype.init(); } aQuery.prototype = {init: function() {this.age = 18return this;},name: function() {},age: 20 }//Uncaught TypeError: Object [object Object] has no method 'name' console.log(aQuery().name())

  拋出錯誤,無法找到這個方法,所以很明顯new的init跟jquery類的this分離了

?


怎么訪問jQuery類原型上的屬性與方法?

???? 做到既能隔離作用域還能使用jQuery原型對象的作用域呢,還能在返回實例中訪問jQuery的原型對象?

實現的關鍵點

// Give the init function the jQuery prototype for later instantiation jQuery.fn.init.prototype = jQuery.fn;

  通過原型傳遞解決問題,把jQuery的原型傳遞給jQuery.prototype.init.prototype

  換句話說jQuery的原型對象覆蓋了init構造器的原型對象

  因為是引用傳遞所以不需要擔心這個循環引用的性能問題

var aQuery = function(selector, context) {return new aQuery.prototype.init(); } aQuery.prototype = {init: function() {return this;},name: function() {return this.age},age: 20 }aQuery.prototype.init.prototype = aQuery.prototype;console.log(aQuery().name()) //20

?

三、鏈式調用

  DOM鏈式調用的處理:

  1.節約JS代碼.

  2.所返回的都是同一個對象,可以提高代碼的效率

?

  通過簡單擴展原型方法并通過return this的形式來實現跨瀏覽器的鏈式調用。

  利用JS下的簡單工廠模式,來將所有對于同一個DOM對象的操作指定同一個實例。

  這個原理就超簡單了

aQuery().init().name()分解 a = aQuery(); a.init() a.name()

  把代碼分解一下,很明顯實現鏈式的基本條件就是實例this的存在,并且是同一個

aQuery.prototype = {init: function() {return this;},name: function() {return this} }

  所以我們在需要鏈式的方法訪問this就可以了,因為返回當前實例的this,從而又可以訪問自己的原型了

aQuery.init().name()

  優點:節省代碼量,提高代碼的效率,代碼看起來更優雅

?

四、插件接口

  jQuery支持自己擴展屬性,這個對外提供了一個接口,jQuery.fn.extend()來對對象增加方法

從jQuery的源碼中可以看到,jQuery.extend和jQuery.fn.extend其實是同指向同一方法的不同引用

jQuery.extend = jQuery.fn.extend = function() { jQuery.extend 對jQuery本身的屬性和方法進行了擴展,擴展工具方法下的插件jQuery.fn.extend 對jQuery.fn的屬性和方法進行了擴展,擴展jquery對象下的插件

  通過extend()函數可以方便快速的擴展功能,不會破壞jQuery的原型結構

  jQuery.extend = jQuery.fn.extend = function(){...}; 這個是連等,也就是2個指向同一個函數,怎么會實現不同的功能呢?這就是this 力量了!

  針對fn與jQuery其實是2個不同的對象,在之前有講述:

  • jQuery.extend 調用的時候,this是指向jQuery對象的(jQuery是函數,也是對象!),所以這里擴展在jQuery上。
  • 而jQuery.fn.extend 調用的時候,this指向fn對象,jQuery.fn 和jQuery.prototype指向同一對象,擴展fn就是擴展jQuery.prototype原型對象。
  • 這里增加的是原型方法,也就是對象方法了。所以jQuery的api中提供了以上2中擴展函數。
1 jQuery.extend = jQuery.fn.extend = function() { 2 var src, copyIsArray, copy, name, options, clone, 3 target = arguments[0] || {}, 4 i = 1, 5 length = arguments.length, 6 deep = false; 7 8 // Handle a deep copy situation 9 //判斷第一個參數是否為boolean類型,也就是是否深度嵌套對象 10 if ( typeof target === "boolean" ) { 11 deep = target; 12 13 // skip the boolean and the target 14 //跳過第一個boolean參數 15 target = arguments[ i ] || {}; 16 i++; 17 } 18 19 // Handle case when target is a string or something (possible in deep copy) 20 // 處理奇怪的情況,比如 jQuery.extend( 'hello' , {nick: 'casper}) 21 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { 22 target = {}; 23 } 24 25 // extend jQuery itself if only one argument is passed 26 if ( i === length ) { 27 target = this; 28 i--; 29 } 30 31 for ( ; i < length; i++ ) { 32 // Only deal with non-null/undefined values 33 if ( (options = arguments[ i ]) != null ) {//opitions為一個個參數對象 34 // Extend the base object 35 for ( name in options ) { 36 src = target[ name ]; 37 copy = options[ name ]; 38 39 // Prevent never-ending loop 40 //防止自引用 41 if ( target === copy ) { 42 continue; 43 } 44 45 // Recurse if we're merging plain objects or arrays 46 //深拷貝 47 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { 48 if ( copyIsArray ) {//被拷貝屬性值是個數組 49 copyIsArray = false; 50 clone = src && jQuery.isArray(src) ? src : []; 51 52 } else { 53 clone = src && jQuery.isPlainObject(src) ? src : {}; 54 } 55 56 // Never move original objects, clone them 57 //遞歸拷貝 58 target[ name ] = jQuery.extend( deep, clone, copy ); 59 60 // Don't bring in undefined values 61 } else if ( copy !== undefined ) {//淺拷貝,屬性值不是自定義 62 target[ name ] = copy; 63 } 64 } 65 } 66 } 67 68 // Return the modified object 69 return target; 70 };

?

?

轉載于:https://www.cnblogs.com/shytong/p/5311108.html

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的【jQuery源码】整体架构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美另类极品videosbest最新版本 | 日本a天堂 | av黄色国产| 亚洲一页 | 东北少妇不戴套对白第一次 | 日韩国产在线一区 | 色在线免费观看 | 黄色一级片 | 亚洲专区中文字幕 | 国产麻豆91视频 | 午夜dv内射一区二区 | 中文有码在线 | 欧美日韩精品一区二区在线观看 | 午夜视频入口 | 成人在线观看免费爱爱 | 少妇av导航 | 波多野结衣在线观看一区二区三区 | 蜜桃视频污在线观看 | 亚洲精品在线一区二区 | 日韩在线观看免费 | 苍井空浴缸大战猛男120分钟 | 久久精品爱| 在线射| 51啪影院 | 亚洲永久精品一区 | 国产免费一区二区三区免费视频 | 精品理论片| 91视频在线观看视频 | 日本视频黄 | 成人免费直播 | av不卡在线免费观看 | 亚洲成人va | www.久久国产 | 波多野结衣之双调教hd | 欧美另类一区二区 | 久久久久亚洲av成人片 | 国产欧美精品一区二区色综合 | 亚洲欧美日本一区 | 免费91网站 | 干丰满少妇| 亚洲综合一二三区 | 午夜精品视频一区 | 最新福利在线 | 91青青草| 啪啪天堂 | 日本一区二区三区网站 | 美女久久久久久久久久 | 天天看片天天干 | 毛片免费一区二区三区 | melody在线高清免费观看 | 无码粉嫩虎白一线天在线观看 | 免费久久久 | 欧美一级特黄视频 | 91视频第一页 | 五月婷婷啪啪 | 一区二区三区免费高清视频 | 波多野结衣一二三四区 | 老司机在线永久免费观看 | 97精品一区| gogo人体做爰大胆视频 | 国产精品久久久久久白浆 | 日本中文在线观看 | 伊人中文字幕在线观看 | 日韩av有码 | 一区二区内射 | 久久久久久人妻一区二区三区 | 日韩欧美在线看 | 91毛片在线观看 | 一色道久久88加勒比一 | 国产精品电影网站 | 波多野结衣视频免费看 | 免费激情av | 全部毛片永久免费看 | 亚洲黄色av网站 | 日韩欧美国产精品综合嫩v 国产小毛片 | 美女福利视频网 | 色悠悠网 | 欧美性爱精品在线 | 日日噜噜夜夜狠狠久久波多野 | 法国空姐在线观看视频 | 成人性生生活性生交全黄 | 亚洲天堂男| 欧美怡红院 | 成人在线视频在线观看 | 亚洲精品99久久久久中文字幕 | 一级性生活黄色片 | 久久高清无码视频 | 日本在线免费看 | 日韩精品在线不卡 | 亚洲成人一级片 | 娇小萝被两个黑人用半米长 | 91国内精品 | 奇米网久久 | 91视频国产免费 | 久久亚洲一区 | 亚洲专区在线播放 | 日本一区二区三区网站 | 国产精品午夜未成人免费观看 | 午夜影院91 |