简体   繁体   中英

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 . But maybe there is some way to make it better and more correctly?

You can get it from name on constructor :

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 ).

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; ). 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. 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:

 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:

 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). If you're using class syntax via a transpiler, it may or may not set name correctly.

Generally object instanceof Process is desirable if it's known for sure that object originates from this class/function. There may be situations where this won't be so. The appearance of several Process can be caused by iframes, multiple package versions, etc.

There is name property that already exists in regular functions class constructors. 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. name cannot be reassigned (in some browsers), so a separate property is needed to identify the class.

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. This may be desirable or not. While instanceof associates class instance with one particular class.

Use .constructor.name on the object. Each object's constructor by default refers to his creation function, which has a name property. It returns the name of the function.

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

Use the name property as follows:

 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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