Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   ES6: Как сделать фабрику методов для класса? (https://javascript.ru/forum/misc/70000-es6-kak-sdelat-fabriku-metodov-dlya-klassa.html)

Shitbox2 02.08.2017 19:23

ES6: Как сделать фабрику методов для класса?
 
Вопрос на самом деле по TypeScript, но он в этом плане полностью копирует ES6.

Есть какой-то класс:
class Dog {
  bulk() {
    ...
  }
}


Нужно определять его методы не вручную, а динамически, примерно так:
function CreateMethod(params) {
  return function() {
     ...
  }
}

class Dog {
  bulk: CreateMethod({name: 'bulk', volume: 90}) //не работает
}


Как это сделать без декораторов методов?

Alexandroppolus 02.08.2017 20:53

Dog.prototype.bulk = CreateMethod({name: 'bulk', volume: 90});


поскольку TypeScript заявлен как "надмножество", а class - как "сахар", то старый добрый способ должен работать, наверно.
и да - понятно, что ссылки на super в методе bulk не будет.

Shitbox2 03.08.2017 03:25

Так можно, но нужно именно в стиле ES6
class Dog {
  bulk: CreateMethod({name: 'bulk', volume: 90})
}

Например, здесь это делается с помощью интерфейса. Хотелось бы фабрику использовать

Shitbox2 03.08.2017 15:38

Rise,
ну, это слишком жестко. Без eval'а нельзя разве?

Shitbox2 03.08.2017 17:51

Всё какие-то запрещённые методы у вас) Это всё равно, что глубокое сравнение объектов делать, сравнивая их json-строки

Shitbox2 03.08.2017 20:20

В TS можно так сделать. Будет работать. Правда, когда применяю к классу декоратор, все такие методы пропадают, но это я как-то декоратор неправильно пишу
function CreateMethod(params) {
  return function() {
     console.log(params)
  }
}

class Dog {
  bulk = CreateMethod({name: 'bulk', volume: 90})
}

Alexandroppolus 03.08.2017 20:51

Цитата:

Сообщение от Shitbox2
Правда, когда применяю к классу декоратор, все такие методы пропадают

куда пропадают?

DjDiablo 03.08.2017 23:48

Цитата:

Правда, когда применяю к классу декоратор, все такие методы пропадают
вероятно от того что все эти свойства в конструкторе создаются

Shitbox2 04.08.2017 12:27

Никуда не пропадают, это я неправильную реализацию написал. Если делать так, то всё работает:
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;
}

Shitbox2 04.08.2017 16:48

Пример декоратора, который я привел, не относится к задаче (т.е. он не участвует в определении методов). Просто я тестировал своё решение в т.ч. со сторонними декораторами, чтобы убедиться, что всё работает как надо.

К сожалению, мой способ не работает в ES6 и это привязывает меня к TS


Часовой пояс GMT +3, время: 14:44.