ES6 Dynamic class names

JavascriptClassEcmascript 6

Javascript Problem Overview


I have been experimenting with ES6 classes and am wondering if you can change class names dynamically? For example

class [Some dynamic name] {}; 

Javascript Solutions


Solution 1 - Javascript

let C = class
{ // ...
}
Object.defineProperty (C, 'name', {value: 'TheName'});

// test: 
let itsName =  (new C()).constructor.name;
// itsName === 'TheName' -> true

Solution 2 - Javascript

There is a pretty simple way to do it:

const nameIt = (name, cls) => ({[name] : class extends cls {}})[name];

Here's the demo.

It uses an object literal to define a field with a desired name that would hold a new class. This causes the new class to automatically get the desired name. After we're done with that, we extract that new class and return it.

Note the parens around the object literal, so that curly braces don't get mistaken for a code block (...) => {...}.

Of course, putting an existing class into named fields won't change the class, so this only works if you are creating a new class. If you only need a dynamic name in one place where you define the class you are naming, you can drop an extra inheritance and just go:

const myClass = {[name]: class {
    ...
}}[name];

Solution 3 - Javascript

There is probably a better solution for whatever you are trying to achieve, but you can assign a class expression to an object:

let classes = {};
classes[someName] = class { ... };

This didn't really change in ES2015: if you want to create a dynamically named binding, you have to use an object or some other mapping instead.

Solution 4 - Javascript

To take it a bit further playing with dynamic class names and dynamic inheritance, when using babel you can just do something like this:

    function withname(name, _parent) {
        return class MyDinamicallyNamedClass extends (_parent||Object) {
            static get name() { return name || _parent.name }
        }
    }

Solution 5 - Javascript

One way, even if not ideal, is simple with eval:

~function() {
    const name = "Lorem"

    eval(`
        var ${name} = class ${name} {} 
    `)

    console.log(Lorem) // class Lorem {}
}()

Note, it has to be with var. Using let, const, and plain class inside the eval won't work.

Another way with Function:

~function() {
    const name = "Lorem"

    const c = new Function(`
        return class ${name} {}
    `)()

    console.log(c) // class Lorem {}
}()

Sitenote: you can pass scope variables into the Function and use them inside:

~function() {
    const name = "Lorem"
    const val = "foo"

    const Class = new Function('val', `
        return class ${name} {
            constructor() {
                console.log( val )
            }
        }
    `)( val )

    console.log(Class) // class Lorem {}
    new Class // "foo"
}()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionsimon-p-rView Question on Stackoverflow
Solution 1 - JavascriptPanu LogicView Answer on Stackoverflow
Solution 2 - JavascriptDaerdemandtView Answer on Stackoverflow
Solution 3 - JavascriptFelix KlingView Answer on Stackoverflow
Solution 4 - JavascriptAnibal AmbertinView Answer on Stackoverflow
Solution 5 - JavascripttrusktrView Answer on Stackoverflow