ES6: Как сделать фабрику методов для класса?
Вопрос на самом деле по TypeScript, но он в этом плане полностью копирует ES6.
Есть какой-то класс: class Dog { bulk() { ... } } Нужно определять его методы не вручную, а динамически, примерно так: function CreateMethod(params) { return function() { ... } } class Dog { bulk: CreateMethod({name: 'bulk', volume: 90}) //не работает } Как это сделать без декораторов методов? |
Dog.prototype.bulk = CreateMethod({name: 'bulk', volume: 90}); поскольку TypeScript заявлен как "надмножество", а class - как "сахар", то старый добрый способ должен работать, наверно. и да - понятно, что ссылки на super в методе bulk не будет. |
Так можно, но нужно именно в стиле ES6
class Dog { bulk: CreateMethod({name: 'bulk', volume: 90}) } Например, здесь это делается с помощью интерфейса. Хотелось бы фабрику использовать |
Rise,
ну, это слишком жестко. Без eval'а нельзя разве? |
Всё какие-то запрещённые методы у вас) Это всё равно, что глубокое сравнение объектов делать, сравнивая их json-строки
|
В TS можно так сделать. Будет работать. Правда, когда применяю к классу декоратор, все такие методы пропадают, но это я как-то декоратор неправильно пишу
function CreateMethod(params) { return function() { console.log(params) } } class Dog { bulk = CreateMethod({name: 'bulk', volume: 90}) } |
Цитата:
|
Цитата:
|
Никуда не пропадают, это я неправильную реализацию написал. Если делать так, то всё работает:
function logClass(target: any) { // сохраняем ссылку на исходный конструктор var original = target; // вспомогательная функция для генерации экземпляров класса function construct(constructor, args) { var c : any = function () { return constructor.apply(this, args); } c.prototype = constructor.prototype; return new c(); } // новое поведение конструктора var f : any = function (...args) { console.log("New: " + original.name); return construct(original, args); } // копируем прототип, чтобы работал оператор instanceof f.prototype = original.prototype; // возвращаем новый конструктор (он переопределит исходный) return f; } |
Пример декоратора, который я привел, не относится к задаче (т.е. он не участвует в определении методов). Просто я тестировал своё решение в т.ч. со сторонними декораторами, чтобы убедиться, что всё работает как надо.
К сожалению, мой способ не работает в ES6 и это привязывает меня к TS |
Часовой пояс GMT +3, время: 14:44. |