4

让我们看下面的示例代码:

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'中创建了一个名为'Test'的类和一个名为'inst'的类的实例。现在我想找出类名。我怎样才能做到这一点?

到目前为止,我通过给每个类一个带有类名的字符串属性来解决这个问题,这样我就可以inst.constructor.className用来访问类名。但如果可能的话,我想停止这样做,因为复制/粘贴类时很容易出错。

如果没有适用于所有当前浏览器的解决方案,也许在未来的某些 ECMAScript 规范中至少有一些新功能可以提供对类名的访问?

4

1 回答 1

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
    }
})();

...这是一个好主意,因为它可以帮助工具帮助您,但是 JavaScript 代码本身没有标准的方法来获得该名称。(但不要这样做ns.Test = function ns_Test() { ... };。它应该可以工作,但是 ECMAScript 的各种实现都有与之相关的各种错误。更多信息请参见上面链接的文章。)


更新:我可能应该说:有非标准的方法可以获得函数的正确名称(ns_Test在我上面的示例中)。

其中最简单的是函数实例的属性,许多name实现都支持它,包括:

  • 火狐的蜘蛛猴
  • 铬的 V8
  • Opera 的引擎(我不知道它的名字)
  • Safari 的引擎(包括 Safari 移动版)

...所以alert(ns_Test.name);会提醒“ns_Test”。但它是非标准的,不支持任何版本的 JScript(微软引擎),甚至不支持 IE9 使用的版本(现在终于发布了!)。这是一个快速测试页面:http: //jsbin.com/oxuva3

请注意,这又是函数的正确名称(参见我上面的示例),而不是您分配给它的属性的名称。

如果name不存在,您可以toString()在函数对象上使用,它可能(或可能不)返回函数的字符串表示形式(例如,“function ns_Test() { ... }”)。这完全是非标准的,但在桌面浏览器中很常见;它不适用于几种移动浏览器,无论如何都可能是个坏主意。:-)

于 2011-03-16T13:45:09.377 回答