简体   繁体   English

如何在 JavaScript 中检索构造函数的名称?

[英]How to retrieve the constructor's name in JavaScript?

Assume the following program:假设有以下程序:

var SomeConstructor = function() { };
var instance = = new SomeConstructor ();

The expression instance instanceof SomeConstructor yields True, so instance has to know somehow that it was constructed by the function SomeConstructor .表达式instance instanceof SomeConstructor产生 True,因此instance必须以某种方式知道它是由函数SomeConstructor构造的。 Is there way to retrieve the name SomeConstructor directly from instance ?有没有办法直接从instance检索名称SomeConstructor

(In my problem at hand, I have a hierarchy of prototypes implementing possible signals in my application. I have to access the type of a signal which shall be equivalent to the constructor used to create that signal.) (在我手头的问题中,我有一个原型层次结构,在我的应用程序中实现了可能的信号。我必须访问信号的类型,该类型应等同于用于创建该信号的构造函数。)

On Chrome (7.0.544.0 dev), if I do:在 Chrome (7.0.544.0 dev) 上,如果我这样做:

function SomeConstructor() { }

var instance = new SomeConstructor();

console.log(instance.constructor.name);

it prints 'SomeConstructor'...but if SomeConstructor is defined as an unnamed function as you have it, it will print an empty string instead.它打印 'SomeConstructor'...但是如果 SomeConstructor 被定义为一个未命名的函数,它将打印一个空字符串。

If I print instance.constructor it prints the same thing as it does if I print SomeConstructor in the code you have.如果我打印instance.constructor它打印的内容与我在您拥有的代码中打印SomeConstructor时打印的内容相同。 The instanceof operator need only compare these two values to see that they are equal to be able to return true . instanceof 操作符只需要比较这两个值,看它们是否相等就可以返回true

This code will get the name of the constructor, as long as it is not an anonymous function:此代码将获取构造函数的名称,只要它不是匿名函数:

obj.constructor.toString().match(/function (\w*)/)[1];

Why would you need the class name?为什么需要类名? Let's say you want to save and restore class instances via JSON.假设您想通过 JSON 保存和恢复类实例。 You could store the class name in a "type" property, and then use a resolver function in JSON.parse to restore the objects.您可以将类名存储在“类型”属性中,然后在 JSON.parse 中使用解析器函数来恢复对象。 (See the sample code on this page ). (请参阅此页面上的示例代码)。

So, in theory you could use the code above to make a generalized serializer that could handle any class instance, but parsing function strings is very inefficient.所以,理论上你可以使用上面的代码来制作一个可以处理任何类实例的通用序列化器,但是解析函数字符串的效率非常低。 This overhead can be avoided by requiring all the classes you are going to store to provide the type explicitly:可以通过要求您要存储的所有类明确提供类型来避免这种开销:

function Foo() {}
Foo.prototype.type = 'Foo';

This seems silly and redundant, which is why I started on the quest to obtain the class name implicitly.这看起来很愚蠢和多余,这就是我开始寻求隐式获取类名的原因。 But in the end I have to give in: there is no acceptable solution in JS :-(但最后我不得不让步:JS 中没有可接受的解决方案 :-(

No. You can use x.constructor to get a direct reference to C , but it's an anonymous function so there's no way of getting its name. x.constructor 。您可以使用x.constructor获得对C的直接引用,但它是一个匿名函数,因此无法获得其名称。

If it were defined like so:如果它是这样定义的:

function C() { };
x = new C();

Then it would be possible to use x.constructor.toString() and parse out the name of the function from the returned string.然后就可以使用x.constructor.toString()并从返回的字符串中解析出函数的名称。 Some browsers would also support x.constructor.name [1] .一些浏览器也会支持x.constructor.name [1]

[1] https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/name [1] https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/name

You can also declare your class this:你也可以这样声明你的类:

var C = function C() { };

Now your C class constructor is a named function (no longer an anonymous function) meaning you can do:现在您的C类构造函数是一个命名函数(不再是匿名函数),这意味着您可以执行以下操作:

x = new C();    

console.log(x.constructor.name); // output: C

This code of yours that needs to know the constructor, can it access the constructor function itself?你的这段代码需要知道构造函数,它可以访问构造函数本身吗? If so, you can just do that instanceof thing.如果是这样,你可以做那个 instanceof 的事情。

It seems that you need to know it by name.看来你需要知道它的名字。 This sounds dangerous.这听起来很危险。 Someone can create another constructor that happen to have the same name and it will pass (unless that's what you want, of course).有人可以创建另一个碰巧具有相同名称的构造函数并且它会通过(当然,除非这是您想要的)。

至少在 React 中它可能是

this.default.name

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM