简体   繁体   English

获取对象的构造函数名称

[英]Get constructor name of object

How can I get name of object's class?如何获取对象类的名称? I mean "Process" in this example我的意思是在这个例子中的“过程” 在此处输入图片说明

I see two ways to get it.我看到有两种方法可以得到它。 First one is to write a getter in this class like第一个是在这个类中编写一个吸气剂,比如

 getClassName(){return "Process"}

But I suppose it will be an error if I try to call this method in object which doesn't belong to this class and hasn't got method like this.但是我想如果我试图在不属于这个类并且没有这样的方法的对象中调用这个方法,那将是一个错误。

And second one is using object instanceof Process .第二个是使用object instanceof Process But maybe there is some way to make it better and more correctly?但也许有一些方法可以使它更好更正确?

You can get it from name on constructor :您可以从constructor name获取它:

console.log(object.constructor.name);

When you do ex = new Example , for instance, in the normal course of things that makes Example.prototype the prototype of the object that was created ( ex ), and the object inherits a constructor property from that object that refers back to the constructor ( Example ).例如,当您执行ex = new Example ,在正常的事情过程中,使Example.prototype成为所创建对象的原型( ex ),并且该对象从该对象继承了一个constructor属性,该属性返回到构造函数( Example )。

I say "in the normal course of things" because there are various ways those normal relationships can be changed.我说“在正常情况下”是因为可以通过多种方式改变这些正常关系。 For instance, code could have overridden the constructor property with an own property on the object ( ex.constructor = somethingElse; ).例如,代码可能已经使用对象上的自己的属性覆盖了constructor属性( ex.constructor = somethingElse; )。 To rule out that specific scenario, you could use:要排除该特定情况,您可以使用:

console.log(Object.getPrototypeOf(object).constructor.name);

Live example:现场示例:

 class Example1 { } const e1 = new Example1(); console.log(e1.constructor.name); // "Example1" class Example2 { constructor() { this.constructor = "I'm special"; } } const e2 = new Example2(); console.log(Object.getPrototypeOf(e2).constructor.name); // "Example2"

The TC39 committee members that specify JavaScript were happy enough to use the instance's constructor property in Promise s when building the new promise that then and catch return (see Step 3 here which goes here and reads constructor from the instance) (and in some other places), so you wouldn't be out on your own if you also used it.在TC39委员会成员指定的JavaScript很高兴足够使用实例的constructor性质的Promise建设新的承诺,当s thencatch回报(见第3步这里肚里这里并读取constructor从实例)(和其他一些地方),因此如果您也使用它,您就不会独自外出。 They don't even go to the prototype of the instance.他们甚至不去研究实例的原型。

But yes, just for completeness, even if you go to the prototype for it, it's still possible for that to lead you astray, since the prototype's constructor property can also be mucked with:但是,是的,只是为了完整起见,即使您访问它的原型,它仍然有可能使您误入歧途,因为原型的constructor属性也可能被混淆:

 class Example { } Example.prototype.constructor = Object; // Why would anyone do this? People are weird. const e = new Example(); console.log(Object.getPrototypeOf(e).constructor.name); // "Object"

It's also possible to redefine the name on a function:也可以在函数上重新定义name

 class Example { } // Why would someone do this? People are weird. Object.defineProperty(Example, "name", { value: "flibberdeegibbit" }); const e = new Example(); console.log(Object.getPrototypeOf(e).constructor.name); // "flibberdeegibbit"

So...caveat user.所以...警告用户。


Note that the function name property is new as of ES2015 (as is class syntax).请注意,函数name属性是 ES2015 的新属性( class语法也是如此)。 If you're using class syntax via a transpiler, it may or may not set name correctly.如果您通过转译器使用class语法,它可能会也可能不会正确设置name

Generally object instanceof Process is desirable if it's known for sure that object originates from this class/function.通常,如果确定object源自此类/函数,则object instanceof Process是可取的。 There may be situations where this won't be so.可能有些情况并非如此。 The appearance of several Process can be caused by iframes, multiple package versions, etc.多个Process的出现可能是由于iframe、多个包版本等原因造成的。

There is name property that already exists in regular functions class constructors.常规函数类构造函数中已经存在name属性 A known pitfall is that it will be mangled in minified code, so it is generally useless in browser JS, and its use can be considered an antipattern.一个已知的陷阱是它会在缩小的代码中被破坏,所以它在浏览器 JS 中通常是无用的,它的使用可以被认为是一种反模式。 name cannot be reassigned (in some browsers), so a separate property is needed to identify the class. name不能重新分配(在某些浏览器中),因此需要一个单独的属性来标识类。

The proper way is to avoid this problem正确的方法是避免这个问题

But I suppose it will be an error if I try to call this method in object which doesn't belong to this class and hasn't got method like this.但是我想如果我试图在不属于这个类并且没有这样的方法的对象中调用这个方法,那将是一个错误。

is to use a getter:是使用吸气剂:

class Process {
  get className() { return 'Process'; }
  ...
}

Or a property:或者一个属性:

class Process {
  ...
}
Process.prototype.className = 'Process';

As a result, there may be several Process classes that have Process className identifier.因此,可能有多个具有Process className标识符的Process类。 This may be desirable or not.这可能是可取的,也可能不是。 While instanceof associates class instance with one particular class.instanceof类实例与一个特定的类相关联。

Use .constructor.name on the object.在对象上使用.constructor.name Each object's constructor by default refers to his creation function, which has a name property.默认情况下,每个对象的构造函数都引用他的创建函数,该函数具有name属性。 It returns the name of the function.它返回函数的名称。

 class SomeClass { } const obj = new SomeClass(); console.log(obj.constructor.name);

Use the name property as follows:使用name属性如下:

 class Process {} console.log(Process.name); const process = new Process; console.log(process.constructor.name);

This is the same way it works for normal prototypal inheritance using functions.这与使用函数的普通原型继承的工作方式相同。

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

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