Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 02.08.2017, 19:23
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 571

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

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


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

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


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

Последний раз редактировалось Shitbox2, 02.08.2017 в 19:29.
Ответить с цитированием
  #2 (permalink)  
Старый 02.08.2017, 20:53
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

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


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

Последний раз редактировалось Alexandroppolus, 02.08.2017 в 21:01.
Ответить с цитированием
  #3 (permalink)  
Старый 03.08.2017, 03:25
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 571

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

Например, здесь это делается с помощью интерфейса. Хотелось бы фабрику использовать
Ответить с цитированием
  #4 (permalink)  
Старый 03.08.2017, 15:38
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 571

Rise,
ну, это слишком жестко. Без eval'а нельзя разве?
Ответить с цитированием
  #5 (permalink)  
Старый 03.08.2017, 17:51
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 571

Всё какие-то запрещённые методы у вас) Это всё равно, что глубокое сравнение объектов делать, сравнивая их json-строки
Ответить с цитированием
  #6 (permalink)  
Старый 03.08.2017, 20:20
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 571

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

class Dog {
  bulk = CreateMethod({name: 'bulk', volume: 90})
}
Ответить с цитированием
  #7 (permalink)  
Старый 03.08.2017, 20:51
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

Сообщение от Shitbox2
Правда, когда применяю к классу декоратор, все такие методы пропадают
куда пропадают?
Ответить с цитированием
  #8 (permalink)  
Старый 03.08.2017, 23:48
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

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

Последний раз редактировалось DjDiablo, 03.08.2017 в 23:50.
Ответить с цитированием
  #9 (permalink)  
Старый 04.08.2017, 12:27
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 571

Никуда не пропадают, это я неправильную реализацию написал. Если делать так, то всё работает:
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;
}
Ответить с цитированием
  #10 (permalink)  
Старый 04.08.2017, 16:48
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 571

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

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



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как сделать tooltip для ячейки таблицы? khusamov ExtJS 7 14.04.2017 10:52
Как сделать выполнение ф-ции только для видимых объектов на экране? Randomizer jQuery 6 21.01.2013 16:06
как сделать событие для списка node. DimaRogov Events/DOM/Window 5 18.09.2011 16:52
Как сделать выпадающее меню voloxa89 jQuery 7 20.08.2011 11:27
Как сделать функцию типа toDataUrl для рисунка в ie6 ? Олег Общие вопросы Javascript 2 14.09.2008 00:06