Имена динамических классов ES6

Я экспериментировал с ES6-классами, и мне интересно, можете ли вы динамически менять имена классов? Например

class [Some dynamic name] {}; 

Ответы

Ответ 1

Возможно, лучшее решение для всего, чего вы пытаетесь достичь, но вы можете назначить выражение класса объекту:

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

Это не изменилось в ES2015: если вы хотите создать динамически именованное связывание, вместо этого вы должны использовать объект или другое сопоставление.

Ответ 2

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

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

Ответ 3

Существует довольно простой способ сделать это:

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

Вот демо.

Он использует литерал объекта для определения поля с нужным именем, которое будет содержать новый класс. Это приводит к тому, что новый класс автоматически получит желаемое имя. После того как мы закончим с этим, мы извлечем этот новый класс и вернем его.

Обратите внимание на parens вокруг объектного литерала, так что фигурные скобки не ошибаются для блока кода (...) => {...}.

Конечно, помещение существующего класса в именованные поля не изменит класс, поэтому это работает только при создании нового класса. Если вам нужно только динамическое имя в одном месте, где вы определяете класс, который вы называете, вы можете удалить дополнительное наследование и просто перейти:

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

Ответ 4

Чтобы немного поиграть с динамическими именами классов и динамическим наследованием, при использовании babel вы можете просто сделать что-то вроде этого:

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

Ответ 5

Один из способов, даже если не идеальный, прост с eval:

~function() {
    const name = "Lorem"

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

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

Обратите внимание, что это должно быть с var. Использование let, const и обычного class внутри eval не будет работать.

Другой способ с Function:

~function() {
    const name = "Lorem"

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

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

Sitenote: вы можете передавать переменные области в Function и использовать их внутри:

~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"
}()

Ответ 6

Пример, с которым я боролся - разрешен следующим образом:

const models = {
  route: mongoose.model('Route'),
  company: mongoose.model('Company'),
  ...
}

а потом:

const name = 'route'
const record = new models[name]()