如果jQuery沒(méi)有插件接口的設(shè)計(jì),那么他就像個(gè)光桿司令沒(méi)有兵,就是沒(méi)有手下,只有自己一個(gè)封閉的城堡。因此jQuery城堡需要設(shè)計(jì)一個(gè)大門(mén) - 插件接口,從而打開(kāi)大門(mén)開(kāi)始招兵買(mǎi)馬。當(dāng)然jQuery除了獲得“開(kāi)發(fā)者社區(qū)”的大力支持外,也有很多大公司紛紛對(duì)它投出了橄欖枝,這也是它成功的關(guān)鍵。
基于插件接口設(shè)計(jì)的好處也是頗多的,其中一個(gè)最重要的好處是把擴(kuò)展的功能從主體框架中剝離出去,降低了框架的復(fù)雜度。接口的設(shè)計(jì)好比電腦上的配件如:CPU、內(nèi)存、硬盤(pán)都是作為獨(dú)立的模塊分離出去了,但是主板提供模塊的接口,例如支持串口的硬盤(pán),我只要這個(gè)硬盤(pán)的接口能插上,甭管是500G還是1000G的容量的硬盤(pán),都能使用。所以在軟件設(shè)計(jì)中插件接口的提供把獨(dú)立的功能與框架以一種很寬松的方式松耦合。
從之前的分析中我們可以知道jQuery對(duì)象的原理,所以一般來(lái)說(shuō),jQuery插件的開(kāi)發(fā)分為兩種:
? 一種是掛在jQuery命名空間下的全局函數(shù),也可稱(chēng)為靜態(tài)方法; ? 另一種是jQuery對(duì)象級(jí)別的方法,即掛在jQuery原型下的方法,這樣通過(guò)選擇器獲取的jQuery對(duì)象實(shí)例也能共享該方法。
提供的接口:
$.extend(target, [object1], [objectN])
接口的使用:
jQuery.extend({ data:function(){}, removeData:function(){} }) jQuery.fn.extend({ data:function(){}, removeData:function(){} })
jQuery的主體框架就是之前提到的那樣,通過(guò)工廠模式返回一個(gè)內(nèi)部的init構(gòu)造器生成的對(duì)象。但是根據(jù)一般設(shè)計(jì)者的習(xí)慣,如果要為jQuery添加靜態(tài)方法或者實(shí)例方法從封裝的角度講是應(yīng)該提供一個(gè)統(tǒng)一的接口才符合設(shè)計(jì)的。
jQuery支持自己擴(kuò)展屬性,這個(gè)對(duì)外提供了一個(gè)接口,jQuery.fn.extend()來(lái)對(duì)對(duì)象增加方法,從jQuery的源碼中可以看到,jQuery.extend和jQuery.fn.extend其實(shí)是同指向同一方法的不同引用。
這里有一個(gè)設(shè)計(jì)的重點(diǎn),通過(guò)調(diào)用的上下文,我們來(lái)確定這個(gè)方法是作為靜態(tài)還是實(shí)例處理,在javascript的世界中一共有四種上下文調(diào)用方式:方法調(diào)用模式、函數(shù)調(diào)用模式、構(gòu)造器調(diào)用模式、apply調(diào)用模式:
? jQuery.extend調(diào)用的時(shí)候上下文指向的是jQuery構(gòu)造器 ? jQuery.fn.extend調(diào)用的時(shí)候上下文指向的是jQuery構(gòu)造器的實(shí)例對(duì)象了
通過(guò)extend()函數(shù)可以方便快速的擴(kuò)展功能,不會(huì)破壞jQuery的原型結(jié)構(gòu),jQuery.extend = jQuery.fn.extend = function(){...}; 這個(gè)是連等,也就是2個(gè)指向同一個(gè)函數(shù),怎么會(huì)實(shí)現(xiàn)不同的功能呢?這就是this力量了!
fn與jQuery其實(shí)是2個(gè)不同的對(duì)象,在之前有講解: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個(gè)擴(kuò)展函數(shù)。
jQuery的extend代碼實(shí)現(xiàn)比較長(zhǎng),我們簡(jiǎn)單說(shuō)一下重點(diǎn):
aAron.extend = aAron.fn.extend = function() { var options, src, copy, target = arguments[0] || {}, i = 1, length = arguments.length; //只有一個(gè)參數(shù),就是對(duì)jQuery自身的擴(kuò)展處理 //extend,fn.extend if (i === length) { target = this; //調(diào)用的上下文對(duì)象jQuery/或者實(shí)例 i--; } for (; i < length; i++) { //從i開(kāi)始取參數(shù),不為空開(kāi)始遍歷 if ((options = arguments[i]) != null) { for (name in options) { copy = options[name]; //覆蓋拷貝 target[name] = copy; } } } return target; }
我來(lái)講解一下上面的代碼:因?yàn)閑xtend的核心功能就是通過(guò)擴(kuò)展收集功能(類(lèi)似于mix混入),所以就會(huì)存在收集對(duì)象(target)與被收集的數(shù)據(jù),因?yàn)閖Query.extend并沒(méi)有明確實(shí)參,而且是通過(guò)arguments來(lái)判斷的,所以這樣處理起來(lái)很靈活。arguments通過(guò)判斷傳遞參數(shù)的數(shù)量可以實(shí)現(xiàn)函數(shù)重載。其中最重要的一段target = this
,通過(guò)調(diào)用的方式我們就能確實(shí)當(dāng)前的this的指向,所以這時(shí)候就能確定target了。最后就很簡(jiǎn)單了,通過(guò)for循環(huán)遍歷把數(shù)據(jù)附加到這個(gè)target上了。當(dāng)然在這個(gè)附加的過(guò)程中我們還可以做數(shù)據(jù)過(guò)濾、深拷貝等一系列的操作了。
請(qǐng)驗(yàn)證,完成請(qǐng)求
由于請(qǐng)求次數(shù)過(guò)多,請(qǐng)先驗(yàn)證,完成再次請(qǐng)求
打開(kāi)微信掃碼自動(dòng)綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書(shū)簽
舉報(bào)