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