jQuery1.5新特征之插件機制的救贖
感覺jQuery1.5***的改變有兩個,jQuery子類與異步列隊,本文只談jQuery子類。
首先要明白為何要推出此功能,是強化它那基本為零的OO功能嗎?不是,從下面的源碼你應該知道它不是讓你自定義類。但這也是個愚蠢的問題,因為這樣,這方法就叫Class,而不是subclass。
- subclass: function(){
- function jQuerySubclass( selector, context ) {
- return new jQuerySubclass.fn.init( selector, context );
- }
- jQuerySubclass.superclass = this;
- jQuerySubclass.fn = jQuerySubclass.prototype = this();
- jQuerySubclass.fn.constructor = jQuerySubclass;
- jQuerySubclass.subclass = this.subclass;
- jQuerySubclass.fn.init = function init( selector, context ) {
- if (context && context instanceof jQuery && !(context instanceof jQuerySubclass)){
- context = jQuerySubclass(context);
- }
- return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass );
- };
- jQuerySubclass.fn.init.prototype = jQuerySubclass.fn;
- var rootjQuerySubclass = jQuerySubclass(document);
- return jQuerySubclass;
- },
我想它真正的用意是為了改善其插件機制。
jQuery的插件是很容易開發,隨便在其原型鏈上添加個方法就叫稱“插件”,因此jQuery的插件很多,垃圾插件也很多,由于停止更新變成垃圾的也很多。
- jQuery.fn.garbage = function(){
- alert("這是垃圾插件!")
- }
當然這是在最理想的情況下,插件才這么簡單(好像一個函數算一個插件也蠻多的)。比如你開發一個插件,然后你同事也開發了一個同名的插件,這時出問題吧。還有這種情況:
- (function($){//插件一
- $.fn.extend({
- a:function(){//插件的主體
- this.b()
- },
- b:function(){}//輔助函數
- })
- })(jQuery);
- (function(){//插件二
- $.fn.extend({
- c:function(){//插件的主體
- this.b()
- },
- b:function(){}//輔助函數
- })
- })(jQuery);
這時這兩個插件混用就有問題了,插件一的b與插件二的b可能不是一個東西,這機率還很大,因為插件一可能是美國的菜鳥開發,插件二是德國的菜鳥開發的,而且外國人都非常喜歡把他們的插件放到jQuery官網的插件展示區,國內的懶鬼兼菜鳥就很容易踩雷了。
插件混亂之災隨著jQuery的流行日益嚴重,由于jQuery易學易用,公司前端不夠人手,隨便抓個后臺就行了。于是前端也像中國樓市那樣出現泡沫了,一個頁面引用N個插件,滿屏的選擇器,維護成本超高,近乎不可能。
歸根結底,問題是大家都在污染jQuery與jQuery.fn這個兩個對象,就像以前大家都愛到全局作用域那里拉屎那樣。全局作用域是公廁,去那兒是不可避免的,但我們可以用子類來轉移jQuery,jQuery.fn的負擔。
在jQuery1.5中,我們就應該這樣寫插件。
- var MyjQuery = jQuery.subclass();
- MyjQuery.fn.writeHello = function(){ this.text('Hello World'); };
- MyjQuery('p').writeHello();
由于MyjQuery是jQuery的子類,因此擁有其所有能力,鏈式操作一樣沒問題。
- MyjQuery('div').css('border', '1px red solid').writeHello();
我們還可以對jQuery原有方法進行修改,不用因為某些隱性bug而改源碼了:
- MyjQuery.fn.text = function(val) {
- var orig = jQuery.fn.text;
- if(typeof val === "string") {
- return orig.call(this, "!!"+ val +"!!");
- } else {
- return orig.apply(this, arguments);
- }
- };
- MyjQuery('.aaa').text("text");
- MyjQuery('.aaa').text();
- //!!text!!
- //不影響jQuery自身
- jQuery('.aaa).text('text'); //text
當然這也帶來一個問題,插件都變為綁定到新的命名空間上了,重新跑到全局作用域上……看來進一步的救贖要等其包加載機制出來了。因此少用插件,提高自身的javascript(非jQuery)能力才是基本。
原文鏈接:http://www.cnblogs.com/rubylouvre/archive/2011/01/21/1940935.html
【編輯推薦】
- 精益求精 jQuery代碼的分析與優化
- jQuery1.5的六大細節改進:DOM操作更簡單
- jQuery入門:數組的三種類型三種操作
- jQuery 1.5***個Beta版發布 付下載
- 10個超贊超實用的免費jQuery圖片插件 附下載
- jQuery 1.5正式版發布 五大變化引人注目