2015-05-26 78 views
1

有鑑於此:在JavaScript中使用字符串進行類型檢測?

function SomeType() { return this; } 

我怎麼能只用一個字符串來檢查對象的類型?

這一切都很好,如果我要構造參考,像這樣:

new SomeType() instanceof SomeType; // true 

但如果我要檢查的類型爲字符串,有沒有簡單的方法來檢查。

new SomeType() instanceof 'SomeType'; // TypeError 

我可以檢查構造函數將其轉換爲字符串後:

function SomeType() { return this; } 

/function \bSomeType\b/.test(String(new SomeType().constructor)); // true 

但它並不適用於所有情況:

var SomeType = function() { return this; } 

/function \bSomeType\b/.test(String(new SomeType().constructor)); // false 

對這個有什麼想法?試圖驗證一個字符串的類型/構造函數是否被認爲是反模式?

+1

*「將嘗試驗證通過單向型/構造 - 字符串被認爲是反模式?「*是的。這也是不可能的,正如你已經看到'var SomeType = function(){...};';該構造函數沒有名稱,所以你不能檢查它。 – Ryan

+0

@minitech我想的很多。我喜歡JavaScript的鬆散打字,直到它傷害了我。 – shennan

回答

1

如何將其與窗口對象?

new SomeType() instanceof window['SomeType']; // true 
+0

我想到了這一點,但這將運行在模塊化程度很高的Node應用程序中,原來的構造函數將超出範圍。 – shennan

0
function SomeType() { return this; } 

var SomeType = function() { return this; }; 

是非常不同的語句。第一個是函數聲明,在執行腳本之前就已經掛起了,並且可以在整個定義範圍內使用。後者是一個函數表達式,爲變量SomeType分配一個未命名和匿名的函數。

在第一種情況下試圖匹配字符串"SomeType"與將對象的構造函數解析爲字符串一樣簡單(new SomeType().constructor.toString())。在後一種情況下,SomeType具有非常不同的含義:它是存儲匿名函數的變量的名稱。您需要一種完全不同的方法來獲取對象實例變量的名稱,例如通過父對象執行循環,以獲取其屬性名稱。

你應該仔細,如果它被寫在假設函數聲明和函數表達式功能相同重新審視你的代碼。

如果你可以只檢查函數聲明(而不是包含函數表達式的變量名)獲得通過,這裏是一個可行的方法:

function isType(obj,name){ 
    var constructor = obj.constructor.toString(); 
    return constructor.slice(9,constructor.indexOf("("))===name; 
} 
+0

我很欣賞你的答案,我已經意識到匿名/命名函數之間的區別。但我的用例相當細微。此外,你的命名函數的方法與我在我的問題中已經概述的方法基本相同。 – shennan

+0

你說得對,這只是獲取相同信息的一種不同方式。但我想你會發現'obj.constructor.toString()'比'String(obj.constructor)'更好的性能。根據我的經驗,RegEx在當前一代瀏覽器中往往沒有得到很好的優化,但未來可能會改變。這裏是一個jsperf來擺弄這些選項:http://jsperf.com/stringifyingaconstructor – Thriggle