2014-03-04 74 views
1

我想實現一種構造函數模式到一個項目的庫中。但是,我想檢查返回對象之前傳遞的某些條件。如果這些條件不符合,那麼我想停止構造函數並返回false停止構造函數

但是,我注意到,無論我設置爲返回值,總是返回一個對象!

即使我這樣做:

new function() { return false; } 

結果仍然是一個Object對象:

在Chrome中:

Chrome console

在Firefox:

Firefox console

有沒有什麼辦法讓構造函數在Javascript中失敗?

回答

5

如果這些條件不符合,那麼我想停止構造函數並返回false。

你不行。構造函數的返回值會被忽略,除非它是非對象的非null。任何原始值(或null)僅被new表達式忽略。

如果你真的想要你有返回的標誌值,你可以這樣做,但它必須是一個對象。 (但它是一個壞主意,詳見下文。)例如: -

// The constructor 
function Foo(num) { 
    if (num < 27) { 
     return Foo.BAD_ARG; // This is a bad idea, see the right way below 
    } 
    this.num = num; 
} 
Foo.BAD_ARG = {}; // Our special "bad argument" object 

有沒有辦法有一個構造函數失敗的Javascript?

是:拋出一個異常:

function Foo(num) { 
    if (num < 27) { 
     throw "`num` must be >= 27"; 
    } 
    this.num = num; 
} 
+0

感謝您的解決方案。我有一個'catch'塊的構造函數,雖然沒有停止構造。你可以看看http://pastebin.com/xnVmZ55Y並告訴我我錯過了什麼嗎? – Martin

+0

@Martin:你不想在構造函數中捕捉異常*,這就是整個問題。您*在構造函數中拋出異常,這會阻止正常返回,從而阻止調用代碼獲取對新創建對象的引用。你在代碼中調用構造函數(或調用它的代碼等)來處理異常,而不是在構造函數中。 –

+0

但是,這不會消耗大量的內存嗎?我不想用額外的標誌創建對象來表明它沒用。我想完全停止構建。 像這樣的東西(http://pastebin.com/rcYTXTzq)會工作,不是嗎? – Martin

1

只返回一個非對象將是包裹你的構造函數中,並將它用new你叫(或不叫)的方式。

要做到這一點,new上的外部功能將需要被禁止。


你甚至可以使用相同的功能,只要你永遠不會new調用它。

function Foo() { 
    if (!(this instanceof Foo)) { 
     if (some_condition) 
      return false; 
     else 
      return new Foo() 
    } 
    // your constructor code here 
} 

var x = Foo(); 

危險是如果你忘記和意外使用new。爲了解決這個問題,你可以使用一個單獨的功能。

function Foo() { 
    // constructor code 
} 

function Bar() { 
    if (this instanceof Bar) 
     throw "Not a constructor" 

    if (some_condition) 
     return false; 
    else 
     return new Foo(); 
} 
1

從堆棧中拋出錯誤,例如,

function thing(){ 
    throw new Error('nope'); 
} 

try { 
    var mine = new thing(); 
} 
catch(e){ 
    mine = null; 
} 

// mine is null 

你也可以做一個排序工廠方法,如:

createThing = function(){ 
    var obj = new thing(); 
    if(obj.feelsOK){ 
     return obj; 
    } 
} 

mine = createThing(); 
// mine is null 
+0

這就是我最終開始做的事情。但是,T.J. Crowder的答案更接近我所期待的。 – Martin