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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With