摘要:的指向的是對象,所以此時擴展的是對象,可以直接通過的方式調用。
寫過jquery插件的人都知道可以通過jquery提供的extend可以對jquery對象進行擴展,而且該方法不僅可以對jquery對象擴展,還能給一個對象添加新的屬性和方法,這個在后面會介紹。
通過不同的方式調用extend擴展的方法也不同:
通過 $.extend() 擴展的是靜態方法;
而通過 $.fn.extend() 擴展的是實例方法。
寫過jQuery插件的通過應該都知道,很多時候我們都是使用extend來為jQuery對象添加插件的。
插件的寫法:
;(function($){ $.fn.extend({ Firstplus: function() {} }); //這樣寫的話插件的使用方法就是:$("div").Firstplus(); $.extend({ Secondplus: function() {} }); //這樣寫的話插件的使用方法就是:$.Secondplus(); })($);
查看源碼的第285行,$.extend()和$.fn.extend()調用的其實是同一個函數,那么他們實現的功能為什么不同呢?
jQuery.extend = jQuery.fn.extend = function() {} //源碼285行
主要是因為這個方法都是將傳入的對象擴展到了this上。
$.extend( xx ) 的this指向的是jQuery對象,所以此時擴展的是jQuery對象,可以直接通過$.xx 的方式調用。
$.fn.extend( xx ) 的this指向的是jQuery對象的prototype,所以此時擴展的jQuery對象的原型,實例化的jQuery對象可以調用所有的jQuyer原型上的方法,可以直接通過 $().xx 的方式調用。
以下是extend的三種不同用法:
jQuery.extend( [ object ] )
>將傳入的 object 擴展到 this 對象上
jQuery.extend( target, [ object1 ,... objectN ] )
>將后面傳入的 object1 到 objectN 擴展到 target 對象上
jQuery.extend( [ deep ], target, [object1,... objectN ] )
>如果傳入了 deep 參數表示遞歸后面傳入object1到objectN對象然后在擴展到target,這樣同名的屬性名就不會被覆蓋了。
具體看下源碼分析:
jQuery.extend = jQuery.fn.extend = function() { //定義了一些變量 var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, //target用來存儲傳入的第一個對象(目標對象) //這個target不僅表示要進行合并的目標對象,也可以表示要擴展到jquery上的對象 i = 1, //i用來表示target后面傳入的對象是arguments的第幾個參數 length = arguments.length, deep = false; //deep變量表示,是否進行深度拷貝 //先進行了一系列的if判斷,來初始化參數,判斷到底是要擴展jQuery還是對傳入的對象進行擴展 //如果第一個參數是布爾類型,則表示是否深度拷貝 if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; //將目標對象置為傳入的第二個參數,如果沒有置為空對象 // skip the boolean and the target i = 2; //將i置為2 } //如果target不是一個對象,將其置為空對象 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } //如果arguments和i相等,表示要擴展的jquery對象,讓target指向this //這個this具體指向什么之前已經探討過了 if ( length === i ) { target = this; --i; //且讓i--,這時arguments[i]表示的才是要擴展到jquery上的對象 } for ( ; i < length; i++ ) { //開始遍歷傳入的 arguments // 只有參數不為空時才執行后面的操作 if ( (options = arguments[ i ]) != null ) { // 對對象進行擴展,無論傳入的target對象,還是jQuery對象,都使用同樣的方法進行擴展 for ( name in options ) { //遍歷傳入的對象的屬性 src = target[ name ]; copy = options[ name ]; //防止target和obj的某個屬性指向的是同一對象進入死循環 if ( target === copy ) { continue; } //是否進行深度拷貝 //這里說的深度拷貝,和我們平時說的深度拷貝有點區別;這里指的當obj的某個屬性是一個對象時,是否對這個屬性繼續遍歷,如果不進行遍歷的話,會直接覆蓋target對象的同名屬性 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { if ( copyIsArray ) { //如果要拷貝的obj屬性為數組 copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { //如果要拷貝的obj屬性為對象 clone = src && jQuery.isPlainObject(src) ? src : {}; } // 進行遞歸,直到屬性不再為一個對象或數組 target[ name ] = jQuery.extend( deep, clone, copy ); } else if ( copy !== undefined ) {//如果不進行深拷貝且當前obj的屬性不為空 //擴展target對象,且和當前obj屬性名相同。 target[ name ] = copy; } } } } return target; 最后返回target對象,如果擴展的jquery對象,則返回的就是jquery對象 };
通過extend函數,可以看出extend函數通過許多的 if 判斷,實現了許多不同的功能:
擴展多個對象到一個對象上;
擴展多個對象到一個對象上,并對要進行擴展的對象進行遍歷,防止將同屬性名的對象覆蓋;
擴展一個對象到jquery對象上;
擴展一個對象到jquery的原型對象上。
后面還可以看到 jq 通過這個方法擴展了很多工具方法到jQuery對象上,不得不說 jq 的結構還是很緊湊的,一個方法不僅提供給外部使用,在內部也多次使用,這不就是傳說中的高內聚么,看樣子看源碼對自己還是有很大的提升的,我是不是又漲見識,哈哈哈哈。
感興趣的話可以看看我的github,不妨給個star。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81293.html
摘要:進一步了解類數組對象可以看這篇文章對象的構建和分離構造器然后我們回來看看,讓我們悲傷的代碼。。。然后又通過下面的語句,將兩個獨立的構造器關聯起來了。 背景 不造輪子的程序員不是好程序員,所以我們今天嘗試造一下輪子。今天的主角是 jQuery ,雖然現在市面上已被 React,Angular,Vue 等擠的容不下它的位置,但是它的簡單 API 設計依然優秀,值得學習和體會。 任務 今天造...
摘要:提高業務編程能力中提供了很多的方法基本都兼容,我們可以使用這些方法快速開發項目中有的方法提供的思想可以讓我們把項目實現得更優化提高基礎以及一些高級編程思想分析源碼,學習里面類庫封裝的思想和一些方法實現的原理有時間把中提供的常用方法都去實現一 jQuery 提高業務編程能力 JQ中提供了很多的方法(基本都兼容),我們可以使用這些方法快速開發項目 JQ中有的方法提供的思想可以讓我們把...
摘要:匿名函數將代碼包裹在里面,防止與其他代碼沖突和污染全局環境。學習整體架構,打造屬于自己的函數式編程類庫讀者發現有不妥或可改善之處,歡迎評論指出。 雖然現在基本不怎么使用jQuery了,但jQuery流行10多年的JS庫,還是有必要學習它的源碼的。也可以學著打造屬于自己的js類庫,求職面試時可以增色不少。 本文章學習的是v3.4.1 版本。unpkg.com源碼地址:https://un...
摘要:這里在函數中有一個的操作,一般構造函數不會這樣寫,但這樣寫并不會影響的結果,這參照之前的分解,便可以推出結果的一致只是返回了不同但值相同的變量。 這篇文章可以說是讀這篇文章這篇文章后的總結。 jQuery最基本的構成結構: var jQuery = window.jQuery = window.$ = function(a,b){ return new jQuery.fn.init...
摘要:干想了半天,認為可能還是本身的寫法問題。對象提供了一種通過定義函數來獲取或設置特定值的方法。簡單來說,給我們暴露了一個鉤子,我們可以自己定義方法比如,來實現針對某個屬性的特定行為。 寫在最前 本次分享一下在一次jQuery賦值樣式失效的結果中來分析背后原因的過程。在翻jQuery源碼的過程中,感覺真是還不能說自己只是會用jQuery,我好像連會用都達不到(逃 歡迎關注我的博客,不定期更...
閱讀 2537·2021-11-24 10:20
閱讀 2385·2021-09-10 10:51
閱讀 3370·2021-09-06 15:02
閱讀 3104·2019-08-30 15:55
閱讀 2835·2019-08-29 18:34
閱讀 3070·2019-08-29 12:14
閱讀 1206·2019-08-26 13:53
閱讀 2916·2019-08-26 13:43