Функция передачи ES6 в качестве примера параметра

Я недостаточно хорошо знаю 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);

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
0
4 262
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Просто присвойте переданную функцию 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');

большое спасибо. Пытаясь применить к моему реальному случаю, я понял, что jobFn должна быть функцией Карри, что означает отсутствие одного или нескольких параметров для выполнения задания DoTheJob. Я обновлю свой вопрос.

xpt 27.01.2019 05:17

Смотрите редактирование, уверен, что фактическое каррирование не требуется, вы можете просто определить другой параметр (или несколько) по мере необходимости и вызвать функцию с дополнительной информацией, которую необходимо передать в

CertainPerformance 27.01.2019 05:33

Замечательно, замечательно! Великолепно и просто - я собирался сказать, что придумал неуклюжий способ сделать это, но прежде чем я начну, вы уже дали обновленный ответ. БОЛЬШОЕ СПАСИБО!!!

xpt 27.01.2019 05:38

В моем случае могу посоветовать, что предикат лучше отдать на 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 28.01.2019 16:08

@xpt Я все еще вижу, что вам не нужно множественное наследование. Почему? Утиная типизация здесь работает безупречно: dailyRoutine находится в B, и вы определяете doTheJob на 8-м уровне... нет проблем: if (this.doTheJob) this.doTheJob (result). Вы поняли идею? В языке с динамической типизацией вы можете делать что-то, если оно есть.

Matías Fidemraizer 28.01.2019 16:41

Хм... Наверное, разные люди создают вещи по-разному. Для меня повторное использование тот же D в разных сценариях с передачей разных функций (с разными параметрами) мне кажется более предпочтительным. Лично я считаю его более чистым, так как мне может понадобиться использовать его в десяти разных сценариях, но не нужно создавать десять разных подклассов только для этого. Но спасибо за помощь - я уверен, что найдутся люди, которые согласятся с вами...

xpt 29.01.2019 20:55

@xpt С моей точки зрения, ваш подход странный: это не ООП и не FP. Это ярлык. Но если вас это устраивает, вы тот, кто реализует проект: D Добро пожаловать.

Matías Fidemraizer 29.01.2019 21:25

Другие вопросы по теме