Имена динамических классов 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]()