2011-03-16 129 views
4

讓我們以下面的例子代碼:如何獲取JavaScript類的名稱

var ns = {}; // Some namespace 

ns.Test = function() 
{ 
    // Constructor of class Test 
}; 

var inst = new ns.Test(); 
var className = hereIsTheMagic(inst); // Must return "ns.Test" 

所以我創建了一個名爲「測試」命名空間「NS」這個類命名爲「出師表」的實例類。現在我想找出類名。我怎樣才能做到這一點?

到目前爲止,我通過給每個類使用類名字符串屬性解決了這個問題,所以我可以使用inst.constructor.className來訪問類名。但如果可能的話,我想停止這樣做,因爲複製/粘貼類時它非常容易出錯。

如果沒有解決方案適用於所有當前的瀏覽器,那麼未來的某些ECMAScript規範中至少會有一些新功能提供對類名的訪問?

+0

不確定這是可能的,但我的問題是你爲什麼要這樣做?大多數情況下,它會毀了你的OOP – Frizi 2011-03-16 13:49:44

+0

@Frizi:我不能說kayahr,但它可以用於錯誤報告。 – 2011-03-16 13:50:30

+0

@Frizi:我主要需要這個對象序列化/反序列化。我剛剛發現Safari支持一個特殊的'displayName'屬性,用於在分析器中命名匿名函數。所以也許這也是一個好主意。所以首先檢查'name',如果不存在,那麼檢查'displayName',我必須爲所有類手動設置。 – kayahr 2011-03-16 15:01:45

回答

8

JavaScript沒有類,它有構造函數和原型鏈。他們在一起可以看起來有點像課堂,但他們確實不是。 :-)

沒有,有那hereIsTheMagic可以找到字符串「ns.Test」在你的榜樣,甚至沒有在ECMAScript中5一方面沒有標準的方式,ns.Test未必指的是功能的唯一屬性(如果你增加ns.OtherTest = ns.Test;,例如)。

的JavaScript確實具有適當的名稱功能的概念,但有訪問函數的正確名稱沒有標準的方式,甚至如果你能,你調用ns.Test功能是匿名。您已將其分配到ns的房產名稱(Test),但該功能沒有。

你可以給功能的名字:

var ns = {}; // Some namespace 
(function() { 
    ns.Test = ns_Test; 

    function ns_Test() { 
    // Constructor of class Test 
    } 
})(); 

...這是一個好主意,因爲它helps tools help you,但有對JavaScript代碼本身,以獲取該名稱沒有標準的方式。 (不要做ns.Test = function ns_Test() { ... };,但它應該工作,但也有有與之相關的各種錯誤的ECMAScript的各種實現更多關於在the article linked above。)


更新:我大概應該有說:有 - 標準函數的名稱(ns_Test在我上面的例子)。

最簡單的,這些是name財產上的功能情況,這是由許多實現,包括支持:

  • Firefox的SpiderMonkey的
  • Chrome的V8
  • Opera的發動機(我不知道知道它的名字)
  • Safari的引擎(包括Safari手機)

... so alert(ns_Test.name);將提醒「ns_Test」。但它是-標準的,不受任何版本的JScript(微軟的引擎)支持,甚至不支持IE9(現在終於發佈!)所使用的版本。這裏有一個快速測試頁面:http://jsbin.com/oxuva3

請注意,這也是該函數的正確名稱(請參閱上面的示例),而不是您分配給它的屬性的名稱。

如果name是不存在的,你可以在函數對象,這可以(或可能不會)返回函數的字符串表示(例如,「功能ns_Test(){...}」上使用toString() )。這完全是非標準的,但在桌面瀏覽器上很常見;它在幾個移動瀏覽器上不起作用,並且在任何情況下都可能是個壞主意。 :-)

+1

很好的解釋,TJ :)我也會拋出在我的[這個兼容表](http://kangax.github.com/es5-compat-table/non-standard/)中,它列出了一些非標準的ES擴展(包括函數的名字屬性) – kangax 2011-03-17 16:16:34

+0

@kangax :乾杯! – 2011-03-17 16:28:22

+0

請注意,您還可以爲函數表達式添加一個名稱:'ns.Test = function ns_Test(){...};'。這個名字也可以通過'ns.Test.name'獲得。 – 2012-02-17 21:55:01