【问题标题】:Determine name of a JavaScript object instance's class确定 JavaScript 对象实例的类的名称
【发布时间】:2012-10-21 01:47:07
【问题描述】:

想象一个 JavaScript“类”Foo

var Foo = function()
{
};

还有那个类的一个实例:

var foo = new Foo();

是否可以直接从实例foo获取字符串Foo,还是Foo只是实例化后无法与实例foo关联的传递变量?


编辑 1 SLaks suggests 使用 foo.constructor。这给出了:

function ()
{
}

如果函数以以下形式定义,则此方法有效:

function Foo()
{}

...但情况可能并非总是如此。


EDIT 2 尝试skizeey's approach 也不起作用。与 Slack 的方法相比,它本质上是一个更完整的尝试,但会产生一个空字符串:""


EDIT 3 我想知道这是否真的可行。请注意来自 Chrome 的 JavaScript 控制台的以下记录:

> var Foo = function() {}
undefined
> var foo = new Foo();
undefined
> foo
Foo

在最后一行中,Chrome 清楚地知道该对象的类型为Foo。然而,这可能只是 Chrome 的东西,而不是标准的 JavaScript,甚至无法从语言本身访问。

【问题讨论】:

  • 你真的需要字符串"Foo"吗?你最终想要做什么?
  • 我正在尝试在我的代码中利用约定。我正在使用 RequireJS 并且知道这个名称意味着我知道该类是在哪个模块中定义的,因此我可以在从本地存储重新饱和数据时再次加载它。
  • 如果您控制所需模块中的构造函数,您可能只需要在其中写入名称。如果您不这样做,那么您是否希望将数据与其原始原型链重新关联?还是仅仅知道要加载哪些模块?
  • @user1689607,从某种意义上说。通过重新加载正确的模块,我将可以访问名称与模块匹配的类的实例。除非有人能找到方法,否则我什至必须将我自己的属性添加到每个符合这种模式的模块中,或者更改我声明构造函数的方式。
  • 通常我建议对构造函数使用命名函数,如果没有别的,它有助于调试。您可以继续使用函数表达式,但使用命名表达式。 var Foo = function Foo() {...}; 虽然我更喜欢标准声明。 function Foo(){...}

标签: javascript reflection prototype-programming


【解决方案1】:

使用命名函数:

> var Foo = function Foo(){};
> undefined
> var foo = new Foo();
> undefined
> foo.constructor.name
> "Foo"

使用未命名函数:

> var Foo = function (){};
> undefined
> var foo = new Foo();
> undefined
> foo.constructor.name
> ""

【讨论】:

    【解决方案2】:

    如果不修改模块代码,就无法实现你想要的。

    当你定义一个像

    这样的函数时
    var Foo = function() {...}
    

    该函数 - 以及使用它作为构造函数创建的任何对象 - 都不知道名称 Foo。您不妨先做var x = 0,然后尝试获取0 的值来告诉您x 的名称。

    【讨论】:

    • 看看我的第三次编辑。 Chrome 不知何故知道类的名称,即使它不是来自命名函数表达式。我想知道这是否属于标准的一部分,或者只是 Chrome 炫耀的一项特权。
    【解决方案3】:

    您可以从foo.constructor 获取Foo 函数。
    但是,您不能将该函数实例与您分配给它的变量的名称相关联。

    【讨论】:

    • 除非你覆盖构造函数属性。
    【解决方案4】:

    来自another thread

    var getName = function(object) { 
      var funcNameRegex = /function (.{1,})\(/;
      var results = (funcNameRegex).exec(object.constructor.toString());
      return (results && results.length > 1) ? results[1] : "";
    };
    

    您实际上只是将整个构造函数作为字符串获取,然后提取其名称。

    但有一个警告:就像 clentfort 在评论 SLaks 的回答时所说的那样,没有人阻止任何人覆盖对象的构造函数属性。

    另一个警告:您还必须明确命名您的函数。

    【讨论】:

    • 还是不行。尝试使用我的问题中的代码示例。它只是返回一个空字符串。
    猜你喜欢
    • 1970-01-01
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2010-12-30
    • 2012-03-02
    • 2021-04-19
    • 1970-01-01
    相关资源
    最近更新 更多