我想實現一種構造函數模式到一個項目的庫中。但是,我想檢查返回對象之前傳遞的某些條件。如果這些條件不符合,那麼我想停止構造函數並返回false
。停止構造函數
但是,我注意到,無論我設置爲返回值,總是返回一個對象!
即使我這樣做:
new function() { return false; }
結果仍然是一個Object
對象:
在Chrome中:
在Firefox:
有沒有什麼辦法讓構造函數在Javascript中失敗?
我想實現一種構造函數模式到一個項目的庫中。但是,我想檢查返回對象之前傳遞的某些條件。如果這些條件不符合,那麼我想停止構造函數並返回false
。停止構造函數
但是,我注意到,無論我設置爲返回值,總是返回一個對象!
即使我這樣做:
new function() { return false; }
結果仍然是一個Object
對象:
在Chrome中:
在Firefox:
有沒有什麼辦法讓構造函數在Javascript中失敗?
如果這些條件不符合,那麼我想停止構造函數並返回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;
}
只返回一個非對象將是包裹你的構造函數中,並將它用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();
}
從堆棧中拋出錯誤,例如,
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
這就是我最終開始做的事情。但是,T.J. Crowder的答案更接近我所期待的。 – Martin
感謝您的解決方案。我有一個'catch'塊的構造函數,雖然沒有停止構造。你可以看看http://pastebin.com/xnVmZ55Y並告訴我我錯過了什麼嗎? – Martin
@Martin:你不想在構造函數中捕捉異常*,這就是整個問題。您*在構造函數中拋出異常,這會阻止正常返回,從而阻止調用代碼獲取對新創建對象的引用。你在代碼中調用構造函數(或調用它的代碼等)來處理異常,而不是在構造函數中。 –
但是,這不會消耗大量的內存嗎?我不想用額外的標誌創建對象來表明它沒用。我想完全停止構建。 像這樣的東西(http://pastebin.com/rcYTXTzq)會工作,不是嗎? – Martin