2012-01-03 77 views
4

我正在學習面向對象的Java腳本。我有以下Factory Method的代碼。調用Javascript工廠方法

function Foo() { 
    var value = 1; 
    return { 
     method: function() { 
      return value; 
     }, 
     value:value 
    } 
} 
Foo.prototype = { 
    bar: function() {} 
}; 

new Foo(); 
Foo(); 

方法Foo可以通過兩種方式調用。 new Foo();Foo();兩者都做同樣的事情和輸出是相同的。 java腳本處理的實際區別是什麼?

+0

請注意,設置'Foo.prototype = {}東西'是沒有意義的,如果你打算從'富返回自己的對象()'函數,而不是去當你說'new Foo()'時,JS爲你創建的對象。 – nnnnnn 2012-01-03 03:47:32

+2

@Bakudan - JavaScript是通過任何合理的術語定義來面向對象的。 – 2012-01-03 03:55:34

+0

@Bakudan,如果您有話要說(面向對象vs基於對象),請用新答案中的示例來證明它的正確性。它會幫助新手:) – 2012-01-03 03:59:54

回答

3

在正常情況下,應該new從創建一個構造函數對象時使用,並回避執行任何其他功能時,呼叫。在函數上使用new時1)創建一個新對象; 2)函數被調用,綁定到該新對象的值爲this,以及3)函數返回的值(默認值)是在第1步中創建的對象。

但是,在你的情況下,你從上面的「構造函數」(不同於上面的對象)返回一個全新的對象),這意味着沒有實際的區別。的this值將仍然是裏面的功能不同,但是這兩個將返回false

new Foo() instanceof Foo; 
Foo() instanceof Foo; 

爲了說明this差,添加以下Foo:當叫

alert(this instanceof Foo) 

new這提醒true;當沒有它時被呼叫,false

此外,還有在分配一個對象Foo.prototype,因爲你永遠不會創建一個能夠利用它(因爲,再一次,你回來的東西從Foo完全不同)的Foo任何情況下,沒有任何意義。

如果你要從Foo返回一個自定義對象,那麼你應該更喜歡沒有new的版本;無論如何,如果您要忽略它並返回完全不同的東西,那麼創建Foo的新實例就毫無意義。

+0

是的。我測試了兩個返回false。 「這個功能的價值會有所不同」的任何小例子? – 2012-01-03 03:36:55

+0

它更好的解釋。 new創建Foo的實例,而沒有新的只保留一個靜態對象,可以隨時使用。正確嗎? – 2012-01-03 03:44:02

+0

此外,設置'Foo。原型「變得毫無意義,因爲你創建的對象不是'Foo'的實例。 – nnnnnn 2012-01-03 03:48:26

2

這裏是一個偉大的鏈接:

Is Javascript "new" considered harmful?

參見:

http://phabricator.com/docs/phabricator/article/Javascript_Pitfalls.html

但在這裏是最好的鏈接(和,真的,在回答你的問題:

http://www.crockford.com/javascript/inheritance.html

JavaScript是一種無類別的面嚮對象語言,因此它使用原型繼承而不是經典繼承。這可以 是令人費解的,以傳統的面嚮對象語言 像C程序員的培訓++和Java ...

+0

謝謝@ paulsm4 :) – 2012-01-03 03:32:07

1

函數中的javascript new關鍵字很奇怪。最好的(只有?)深入解釋我已經能夠找到的事情實際上是Daniel Howard的this SO answer

對於任何想學習一些更高級的Javavscript概念的人來說,都應該要求閱讀。

順便說一句,你可以得到真的遠在js永遠不會使用新的關鍵字。注意基本上沒有任何使用jQuery的代碼依賴於它。

0

因爲您從Foo返回對象,所以使用new不起作用。 Foo()new Foo()的返回值將爲而非Foo的實例;相反,它們將是您返回的任何值的類型的實例。

如果從構造函數中返回任何†對象或任何函數,則會看到相同的行爲。 然而,如果Foo是返回:

  • 的字符串
  • 一些
  • null
  • undefined(同什麼都沒有返回)
  • this

...然後是的返回值Foo的實例。

您可以測試出下面的代碼上JSFiddle

function ReturnsString() { return "string"; } 
function ReturnsNumber() { return 1; } 
function ReturnsNull() { return null; } 
function ReturnsUndefined() { return void 0; } 
function ReturnsThis() { return this; } 
function ReturnsFunction() { return function() {}; } 
function ReturnsObject() { return {}; } 

alert("Results:" 
    + "\nReturnsString: " + (new ReturnsString() instanceof ReturnsString) 
    + "\nReturnsNumber: " + (new ReturnsNumber() instanceof ReturnsNumber) 
    + "\nReturnsNull: " + (new ReturnsNull() instanceof ReturnsNull) 
    + "\nReturnsUndefined: " + (new ReturnsUndefined() instanceof ReturnsUndefined) 
    + "\nReturnsThis: " + (new ReturnsThis() instanceof ReturnsThis) 
    + "\nReturnsFunction: " + (new ReturnsFunction() instanceof ReturnsFunction) 
    + "\nReturnsObject: " + (new ReturnsObject() instanceof ReturnsObject) 
); 

ReturnsFunctionReturnsObject構造均會顯示一個false結果,這意味着與new運營商使用的時候不返回instanceof自己。

所有其他構造函數donew運算符一起使用時會自行返回instanceof本身。

†除this,正如我上面提到

+0

你的意思是,函數和對象不返回它自己的實例。所以Foo()和新的Foo()也不會。但是,如果他們返回別的東西。他們是他們自己實例的一部分! – 2012-01-03 04:23:28

+0

@ Umesh,這是完全正確的。我覺得這種行爲非常不直觀!感謝上帝[Coffeescript](http://coffeescript.org/)。 ;) – aeskr 2012-01-03 04:26:50