2009-12-06 29 views
0

我嘗試創建一些基於類的jQuery風格,如下面的代碼。爲什麼jQuery使用「new jQuery.fn.init()」來創建jQuery對象,但我不能?

myClass = window.myClass = function(x, y) 
{ 
    return new myClass.fn.init(x, y); 
}; 

myClass.fn = myClass.prototype = 
{ 
    init: function(x, y) 
    { 
     // logic for creating new myClass object. 
    } 
}; 

我不明白爲什麼jQuery的使用new關鍵字,因爲從我的實驗創建它的類,JavaScript的始終創建myClass.init對象,而不是MyClass的對象。但是,我嘗試刪除myClass構造函數中的新關鍵字。但它仍然沒有改變。你能解釋爲什麼jQuery可以做到這一點,但我不能或給我一些代碼在init函數中使用?

順便說一句,我可以使用下面的代碼而不是jQuery樣式代碼來創建相同的對象。我的代碼& jQuery代碼有什麼不同?使用jQuery風格有什麼好處嗎?

myClass = window.myClass = function(x, y) 
{ 
    this.init(x, y); 
}; 

myClass.fn = myClass.prototype = 
{ 
    init: function(x, y) 
    { 
     this.x = x; 
     this.y = y; 
    } 
}; 

PS。我喜歡將初始邏輯分解爲函數的編寫代碼,因爲使用我的代碼的其他人(如我的下面的代碼)很容易覆蓋此函數。

// override init function of myClass 
myClass.fn._old_init = myClass.fn.init; 
myClass.fn.init = function() 
{ 
    // logic for doing something before init 

    this._old_init(); 

    // logic for doing something after init 
}; 

感謝,

回答

0

jQuery對象初始化應該像下面的代碼。

jQuery = window.jQuery = window.$ = function (x, y) 
{ 
    return new jQuery.fn.init(x, y); 
}; 

jQuery.fn = jQuery.prototype = 
{ 
    init: function() 
    { 
     // some logic for object initialization 
     return this; 
    } 
}; 

jQuery.fn.init.prototype = jQuery.fn; 

這段代碼唯一的一個好處是它總是創建jQuery對象的實例,儘管您不使用new關鍵字來創建對象。

另一方面,如果您在調用初始化對象時不使用new關鍵字,那麼使用初始化對象的init函數的代碼不起作用。爲了修復它,你必須添加一些代碼,比如「J-P」示例來檢查這個對象。如果它的類型不是當前類,它將自動爲其創建實例。

這兩個代碼應該可以正常工作。但我喜歡jQuery風格而不是「J-P」風格,因爲它很容易閱讀和修改。

感謝,

2

這種方法應該很好地工作。你可能會錯過的一件事是,使用這種技術,你不會創建一個myClass的實例;你將要創建一個myClass.prototype.init的實例。

因此,myClass.prototype中定義的任何方法都不適用於該實例。你要確保在init的原型點myClass的原型:

myClass.fn.init.prototype = myClass.fn; 

FWIW,我沒有看到這種做法的任何實際的好處。這有什麼問題? -

function myClass(x,y) { 

    if (!(this instanceof myClass)) { 
     return new myClass(x,y); 
    } 

    // Prepare instance 

} 

myClass.prototype = { /* Methods */ }; 

// It can still be overwritten: 

var oldMyClass = myClass; 

function myClass(x,y) { 

    // Hack some stuff here... 

    return new oldMyClass(x,y); 
} 
+0

,因爲我剛剛發現,jQuery的使用這個語句(jQuery.fn.init.prototype = jQuery.fn)給了init函數jQuery的原型後實例你的回答是真實的。然而,你的回答和你的例子並沒有解決我的問題,爲什麼jQuery使用這種風格來創建jQuery對象。 – 2009-12-07 07:37:15

+0

jQuery可能使用這種技術將構造函數與通用包裝函數('jQuery()')分開。他們可以做到這一點,這可能是一個很早就在jQuery開發中做出的決定,並沒有改變,因爲它似乎有效地工作...... – James 2009-12-07 09:57:16

+0

@JP - 同意這可能是對早期決定的回憶 – 2009-12-07 17:54:13

0

我不能完全肯定的問題是什麼,但我會盡我所能回答什麼,我想你問。

new關鍵字用於實例化由功能原型上的init屬性定義的函數返回的對象的新實例。

我相信代碼是用這種方式,使得new關鍵字每次不要求你實例化一個新的jQuery 對象並委派對象的構造原型背後的邏輯。前者我相信是使庫清潔器使用和後者保持初始化邏輯乾淨地在一個地方,並允許init遞歸調用構造並返回一個對象,正確匹配傳遞的參數。

您的第二個代碼塊不返回對象。在Firebug中試用它

var myClass1 = myClass(1,2); 
console.log(myClass1); 

你得到this.init is not a function錯誤。這將工作的唯一方法是,如果你使用new關鍵字在

var myClass1 = new myClass(1,2); 
console.log(myClass1); 

與此相比,在每種情況下類似於代碼jQuery中

myClass = window.myClass = function(x, y) 
{ 
    return new myClass.fn.init(x, y); 
}; 

myClass.fn = myClass.prototype = 
{ 
    init: function(x, y) 
    { 
     this.x = x; 
     this.y = y; 
    } 
}; 

var myClass1 = myClass(1,2); 
console.log(myClass1); 

var myClass2 = new myClass(1,2); 
console.log(myClass2); 

,你正確地得到它返回一個對象x屬性值爲1,y屬性值爲2,是否使用new關鍵字。

+0

我只是在我的回答中告訴你。當您不使用新關鍵字時,我的問題中的代碼不起作用。 – 2009-12-07 14:03:19

+1

從你的問題的措辭中不清楚這是你在說什麼 – 2009-12-07 14:15:48

相關問題