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