Get the class name of an instance of an ES6 class

Are there any “harmonious” ways to get the class name from an instance of the ES6 class? Besides

someClassInstance.constructor.name 

I am currently looking forward to implementing Traceur. And it looks like Babel has a polyfill for Function.name , while Traceur does not.

To summarize: there was no other way in ES6 / ES2015 / Harmony and nothing is expected. ATM in ES.Next.

It can provide useful templates for uninitiated server applications, but is not desirable in applications designed for a browser / desktop / mobile phone.

Babel uses core-js for the polyfill Function.name , it must be loaded manually for the Traceur and TypeScript applications, if necessary.

+112
javascript ecmascript-6 traceur
Mar 27 '15 at 21:31
source share
3 answers

someClassInstance.constructor.name is exactly the right way to do this. Transpilers may not support this, but this is the standard way for specs. (The name property of functions declared through ClassDeclaration productions is set in clause 14.5.15 , step 6.)

+145
May 31 '15 at 17:43
source share

As @Domenic says, use someClassInstance.constructor.name . @Esteban mentions in the comments that

someClassInstance.constructor is a function. All functions have the name property ...

So, to access the class name statically, do the following (this works with my version of Babel BTW. According to comments on @Domenic, your mileage may vary).

 class SomeClass { constructor() {} } var someClassInstance = new SomeClass(); someClassInstance.constructor.name; // === 'SomeClass' SomeClass.name // === 'SomeClass' 

Update

Babylon was fine, but to coalize / minimize ended up causing me problems. I make a game and create a hash of the combined Sprite resources (where the key is the name of the function). After minimization, each function / class was called t . This kills the hash. I use Gulp in this project, and after reading gulp -uglify docs, I found that there is a parameter to prevent this local variable / function name mangling from happening. So in my gulpfile I changed

.pipe($.uglify()) to .pipe($.uglify({ mangle: false }))

There is a tradeoff in performance and readability. Incorrect use of names will result in a (slightly larger) build file (more network resources) and potentially slower code execution (link - may be BS). On the other hand, if I kept the same, I would have to manually define getClassName for each ES6 class - at the static level and instance level. No thanks!

Update

After discussion in the comments, it seems that avoiding the .name convention in favor of defining these functions is a good paradigm. This takes only a few lines of code and will completely minimize and generalize your code (if used in the library). Therefore, I think I will change my mind and manually define getClassName for my classes. Thanks @estus! . Getter / Setters is usually a good idea compared to direct access to a variable anyway, especially in a client application.

 class SomeClass { constructor() {} static getClassName(){ return 'SomeClass'; } getClassName(){ return SomeClass.getClassName(); } } var someClassInstance = new SomeClass(); someClassInstance.constructor.getClassName(); // === 'SomeClass' (static fn) someClassInstance.getClassName(); // === 'SomeClass' (instance fn) SomeClass.getClassName() // === 'SomeClass' (static fn) 
+38
Sep 16 '16 at 1:01
source share

Getting class name directly from class

The previous answers explained that someClassInstance.constructor.name works fine, but if you need to programmatically convert the class name to a string and don’t want to create an instance for this, remember that:

 typeof YourClass === "function" 

And since each function has a name property, another good way to get a string with your class name is to simply do:

 YourClass.name 

The following is a good example of why this is useful.

Download web components

As the MDN documentation teaches us, so you download the web component:

 customElements.define("your-component", YourComponent); 

Where YourComponent is a class extending from HTMLElement . Since it is considered good practice to name your component class after the component tag itself, it would be nice to write a helper function that all your components could use to register. So here is this function:

 function registerComponent(componentClass) { const componentName = upperCamelCaseToSnakeCase(componentClass.name); customElements.define(componentName, componentClass); } 

So all you have to do is:

 registerComponent(YourComponent); 

This is good because it is less error prone than the component tag record itself. To wrap it, this is upperCamelCaseToSnakeCase() :

 // converts 'YourString' into 'your-string' function upperCamelCaseToSnakeCase(value) { return value // first char to lower case .replace(/^([AZ])/, $1 => $1.toLowerCase()) // following upper chars get preceded with a dash .replace(/([AZ])/g, $1 => "-" + $1.toLowerCase()); } 
+3
Sep 15 '18 at 22:35
source share



All Articles