如何在JavaScript中查找有命名空间的构造函数的函数名称?

3
例如,比较以下两个例子:
function Person(name) {
 this.name = name;
}
var john = new Person('John');
console.log(john.constructor);
// outputs: Person(name)

var MyJSLib = {
 Person : function (name) {
   this.name = name;
 }
}
var john2 = new MyJSLib.Person('John');
console.log(john2.constructor);
// outputs: function()

第一种形式在运行时调试很有用。第二种形式需要一些额外的步骤来确定您拥有什么类型的对象。

我知道我可以编写一个描述性的toString函数或调用构造函数上的toSource方法来获取更多信息,但我想要尽可能简单的方法。

有没有办法做到这一点?有什么建议吗?

3个回答

6

发生这种情况是因为您正在使用匿名函数。

您可以指定匿名函数的名称(是的,听起来很奇怪),您可以:

var MyJSLib = {
 Person : function Person (name) {
   this.name = name;
 }
}
var john2 = new MyJSLib.Person('John');
console.log(john2.constructor);

匿名函数可以被命名,但这些名称仅在函数内部可见。由于使用了new运算符,构造函数属性将会被设置,您将能够看到名称。

您还可以使用或不使用函数名称来比较构造函数引用:

console.log(john2.constructor === MyJSLib.Person); // true

+1,谢谢!我没有尝试过那个,而且我本来会错误地认为form会将Person构造函数引入全局命名空间。知道这点很好。 - Keith Bentrup
匿名函数之所以匿名,是有原因的 :) 在这个属性赋值的右侧,你所拥有的仅仅是一个函数表达式(根据定义,它可以有可选的标识符)。 - kangax

3

如果您想检查一个对象是否是特定类的实例,则可以使用“instanceof”关键字进行检查。如果您明确需要构造函数的名称(我真的看不出有什么意义),则可以尝试下面的代码

var MyJSLib = {
 Person : function Person(name) {
   this.name = name;
 }
}

john2 instanceof MyJSLib.Person 返回 true。但我猜测 OP 不想针对特定名称进行测试。 - Russ Cam
我给出了第二个答案,与在我之后不久发送的CMS答案相同。谢谢兄弟... - BYK
我没有给你点踩,我只是想为你的回答提供更多的细节。 - Russ Cam
所以谁做了,那么感谢他=)真正的和衷心的感谢你的尝试解释;) - BYK

-1
你想要的是命名空间中持有者的名称。
function getName(namespace, obj) {
  for name in namespace:
    if (namespace[name] == obj) return name;
}
console.log(getNameOf(MyJSLib, john2.constructor));

这在Keith Bentrup给出的代码中绝对行不通。要让它工作,你应该进行递归查找。但那会非常慢。 - BYK
将窗口更改为命名空间变量。这里没有递归。 - M. Utku ALTINKAYA
那不是一个好的方式。请注意我所说的:“它应该是递归的”,尽管它不是。 - BYK
请定义一个良好的方式,作为变量的实际名称,没有其他方法。因为他表明不想要像stingTo这样的方法,所以请返回类名。而且他在哪里提到了递归的事情?我没有看到其中有命名空间。即使它是一个要求,也只能将这些命名空间添加到预定义的容器中等。我只是想指出,名称仅在命名空间中有意义,它不是真正的标识符。 - M. Utku ALTINKAYA
请查看我的答案和被接受的答案。如果您可以在一个步骤中处理所有条件,并且有另一种需要递归处理所有条件的方法,则递归方式当然是“不好的”。 - BYK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接