Я недостаточно хорошо знаю JS/ES6, чтобы описать свой вопрос в коде. Так что большая часть этого вопроса концептуально и в псевдокоде.
Скажем, у меня есть такой класс Contractor:
class Contractor {
constructor(jobFn) {
// save jobFn;
}
dailyRoutine() {
// let result = DriveToWork()
const result = 6
DoTheJob(result)
DriveBackHome()
}
}
Проблема в том, что то, что делает DoTheJob(), может быть разным в разных местах.
Так что в месте А может быть
he = new Contractor(write_front_end(with, this, and that))
А на месте Б может быть
he = new Contractor(fix_backend_node(with, express))
То есть поведение должно быть передано во время конструктора, и действие может потребовать другого типа и другого количества параметров.
Возможно ли это с ES6?
Пожалуйста, покажите код ES6, который может передавать функцию с разным типом и разным количеством параметров через конструктор в DoTheJob().
Кроме того, проблема заключается в том, что jobFn должен быть функцией Карри, что означает отсутствие одного или нескольких параметров для выполнения задания DoTheJob. Скажем, если jobFn передан с Карриadd(3), то DoTheJob выполнит UncurriedAdd add(3, 6); если затем jobFn передается с Карриmultiple(5), то DoTheJob будет выполнять Uncurried из multiple(5, 6);



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Просто присвойте переданную функцию this.DoTheJob, а затем вызовите this.DoTheJob внутри dailyRoutine:
class Contractor {
constructor(jobFn) {
this.DoTheJob = jobFn;
}
dailyRoutine() {
// DriveToWork()
this.DoTheJob();
// DriveBackHome()
}
}
const c1 = new Contractor(() => console.info('doing job A'));
c1.dailyRoutine();
const c2 = new Contractor(() => console.info('doing job B'));
c2.dailyRoutine();
// c1 again:
c1.dailyRoutine();
// feel free to reference any in-scope variables in the passed function,
// no need to pass the variables as additional parameters
const data = 'data';
const c3 = new Contractor(() => console.info('data is', data));
c3.dailyRoutine();Если dailyRoutine необходимо вызвать с данными, которые необходимо отправить в переданную функцию doTheJob, просто определите необходимые аргументы в функции, которую вы передаете, здесь нет необходимости в фактическом каррировании:
class Contractor {
constructor(jobFn) {
this.DoTheJob = jobFn;
}
dailyRoutine(doJobArg) {
this.DoTheJob(doJobArg);
}
}
// feel free to reference any in-scope variables in the passed function,
// no need to pass the variables as additional parameters
const data = 'data';
const c3 = new Contractor((arg) => console.info('data is', data, 'and arg is', arg));
c3.dailyRoutine('argDoTheJobIsCalledWith');Смотрите редактирование, уверен, что фактическое каррирование не требуется, вы можете просто определить другой параметр (или несколько) по мере необходимости и вызвать функцию с дополнительной информацией, которую необходимо передать в
Замечательно, замечательно! Великолепно и просто - я собирался сказать, что придумал неуклюжий способ сделать это, но прежде чем я начну, вы уже дали обновленный ответ. БОЛЬШОЕ СПАСИБО!!!
В моем случае могу посоветовать, что предикат лучше отдать на dailyRoutine, потому что таким образом вы сможете повторно использовать один и тот же экземпляр и давать разные предикаты.
Во всяком случае, для этого есть чистое ООП-решение, использующее полиморфизм методов, способ JavaScript (также известный как утиная печать):
class Contractor {
driveBackHome() {}
dailyRoutine() {
const result = 6
this.doTheJob(result)
this.driveBackHome()
}
}
class SpecializedContractorA extends Contractor {
doTheJob(result) {
console.info('aaaaaaaaaaaaaaaaaaaaa', result)
}
}
class SpecializedContractorB extends Contractor {
doTheJob(result) {
console.info('bbbbbbbbbbbbbbbb', result)
}
}
const a = new SpecializedContractorA()
a.dailyRoutine()
const b = new SpecializedContractorB()
b.dailyRoutine()Спасибо за ответ. Для простоты и для того, чтобы сосредоточиться на моем вопросе, я опустил кровавые подробности моего реального случая, когда класс, который я использую, находится на 4-м уровне подкласса D: A <- B <- C <- D, тогда как dailyRoutine определяется на 2-м уровне (В). Поскольку я считаю, что множественное наследование не поддерживается JS/ES6, я думаю, что передача функции с другим типом и другим количеством параметров будет лучшим подходом.
@xpt Я все еще вижу, что вам не нужно множественное наследование. Почему? Утиная типизация здесь работает безупречно: dailyRoutine находится в B, и вы определяете doTheJob на 8-м уровне... нет проблем: if (this.doTheJob) this.doTheJob (result). Вы поняли идею? В языке с динамической типизацией вы можете делать что-то, если оно есть.
Хм... Наверное, разные люди создают вещи по-разному. Для меня повторное использование тот же D в разных сценариях с передачей разных функций (с разными параметрами) мне кажется более предпочтительным. Лично я считаю его более чистым, так как мне может понадобиться использовать его в десяти разных сценариях, но не нужно создавать десять разных подклассов только для этого. Но спасибо за помощь - я уверен, что найдутся люди, которые согласятся с вами...
@xpt С моей точки зрения, ваш подход странный: это не ООП и не FP. Это ярлык. Но если вас это устраивает, вы тот, кто реализует проект: D Добро пожаловать.
большое спасибо. Пытаясь применить к моему реальному случаю, я понял, что
jobFnдолжна быть функцией Карри, что означает отсутствие одного или нескольких параметров для выполнения заданияDoTheJob. Я обновлю свой вопрос.