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