this.myName="literallycopiedclassname"
Is not the same as
this.myName=this.constructor.name
Look at this:
class B extends Error {
constructor() {
super();
this.myName="B";
}
};
class D extends B {constructor() {super();}};
let o=new D(); console.log(o.myName);
And this:
class B extends Error {
constructor() {
super();
this.myName=this.constructor.name;
}
};
class D extends B {constructor() {super();}};
let o=new D(); console.log(o.myName);
As I know, you cannot access static class properties from within constructor of that class an easy way, except when explicitly referencing the class:
this.myName=B.name;
However, you can access static properties of the outermost class of the constructors super()-chain (the class of object being constructed) (and of its ancestors) using this.constructor
. If it is, what you want, enjoy the this.constructor.name
construction.
If you want to record the class name from within the constructor defined by that class, you need to explicitly reference the class, but then you need to write it's identifier once more as well. However, it doesn't need to be a string literal, as shown above. If the reason for your question is that you dislike using string literals where not necessary and/or you will avoid maintaining all the identifier-names and literals when renaming the class(es), you can try the following:
If you write
class B extends Error {};
Then B
is an identifier refering to the class being defined, accessible in the class' body, AND that class' static property "name" (B.name
) is set to it's literal representation (B.name="B"
). Additionally, if written this way, it behaves like this:
B=class B extends Error {};
So you can reference the class with B
from outside the class' body as well. But you can also write
C=class B extends Error {};
Than you can reference the class with C
from outside, with B
from inside and the "name" property becomes "B"
. It shows, that the "internal" name can differ from the name of variable holding the reference to the class. You can name it at will and there is no need to rename it:
const C=class ThisClass extends Error {
constructor() {
super();
this.myName=ThisClass.name;
}
};
let o=new C();
The drawback is, that your class will have the internal name ThisClass
. It may or may not be wrong, all classes can have the same internal name without interferring, when you don't use it for some (e.g. debug) purposes. After all, the internal name can be reassigned (again, to whatever you want):
Object.defineProperty(C,"name",{value:"C", configurable:true});
However, you have to write it as a string literal again. But there is a workaround:
You can save the reference to the class whereever you want:
const cName="YourClass";
const classes={};
classes[cName]=class ThisClass extends Error {};
All put together:
const cName="YourClass";
const classes={};
Object.defineProperty (
classes[cName]=class ThisClass extends Error {
constructor() {
super();
this.myName=ThisClass.name;
}
},
"name",
{value:cName, configurable:true}
);
class D extends classes[cName] {
constructor() {super();}
};
let o=new (classes[cName])();
console.log("YourClass myName", o.myName);
console.log("YourClass constructor", o.constructor.name);
let od=new D();
console.log("D myName", od.myName);
console.log("D constructor", od.constructor.name);
Now there is only one place, where the class name is specified, as string literal. And you don't need to rewrite the name in new...