Пожалуйста, объясните мне функцию обратного вызова, как будто мне 5 лет

#javascript #callback

#javascript #обратный вызов

Вопрос:

Я только что написал этот код:

 function doOperation(val1, val2, operation){
    
    operation(val1, val2);
    
    }
    
function sum (a, b){
    
    console.log(a b);
    
    }
    
    doOperation(2,4,sum);
  

Как вы можете видеть в этом коде, я использую функцию обратного вызова (sum). Однако параметр функции (operation(val1, val2)) внутри основной функции и функции обратного вызова (sum) совершенно разные, и это меня смущает.

Еще раз, функция operation принимает эти два именованных параметра: «val1» и «val2»

Однако, когда мы передаем функцию обратного вызова, мы передаем «a» и «b» в качестве параметра.

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

Кто-нибудь может объяснить, как можно иметь разные имена параметров или я что-то упускаю ?!

Комментарии:

1. Третий параметр operation — это ссылка на функцию, которую вы передаете ей. Это просто псевдоним.

2. На самом деле это вообще не связано с функцией обратного вызова. Имя переменной, которую вы передаете в качестве параметра, не обязательно должно совпадать с именем параметра (действительно, когда вы вызываете doOperation , значения 2 и 4 вообще не присваиваются именам; вам не нужно делать const val1 = 2, val2 = 4; заранее).

Ответ №1:

 doOperation(2,4,sum);
  

Вы вызываете doOperation с тремя аргументами. Третья функция оказывается функцией.

 function doOperation(val1, val2, operation){
  

Значение третьего аргумента doOperation присваивается переменной с именем operation .

 operation(val1, val2);
  

operation вызывается как функция (что нормально, переданное значение является функцией).

Ему передаются два аргумента. val1 и val2 это первые два переданных аргумента doOperation .

 function sum (a, b){
  

Функция ожидает два аргумента, они присваиваются переменным a и b .

… и так далее.


Если функция обратного вызова заменяет какую функцию внутри основной функции

Функция обратного вызова ничего не заменяет.

Кто-нибудь может объяснить, как можно иметь разные имена параметров

Когда вы вызываете функцию, вы помещаете ряд выражений между ( и ) .

 doOperation(2,4,sum);
  

В приведенном выше случае это два числовых литерала и переменная, содержащая функцию.

Значения передаются переменным, определенным в определении функции:

 function doOperation(val1, val2, operation){
  

Так 2 идет val1 и так далее.

Ответ №2:

operation Обратный вызов — это просто функция, которую вы передаете doOperation функции. doOperation Функция принимает два значения и передает их operation функции.

Лучшим примером того, что происходит, было бы показать, как operation можно вызвать несколько функций обратного вызова.

 const doOperation = (v1, v2, fn) => fn(v1, v2); // or fn.call(null, v1, v2)
    
const operations = {
  sum        : (a, b) => a   b,
  difference : (a, b) => a - b,
  product    : (a, b) => a * b,
  quotient   : (a, b) => a / b
};

const x = 2, y = 4;

// Direct reference to operations
console.log(doOperation(x, y, operations.sum));        // 6
console.log(doOperation(x, y, operations.difference)); // -2
console.log(doOperation(x, y, operations.product));    // 8
console.log(doOperation(x, y, operations.quotient));   // 0.5

// Dynamic reference to operations
for (const operation in operations) {
  console.log(doOperation(x, y, operations[operation]));
}  
 .as-console-wrapper { top: 0; max-height: 100% !important; }  

Редукторы и сортировщики в значительной степени зависят от типов обратных вызовов, показанных выше.

 const values = [ 1, 2, 3 ];
    
const operations = {
  sum        : (a, b) => a   b,
  difference : (a, b) => a - b,
  product    : (a, b) => a * b,
  quotient   : (a, b) => a / b
};

console.log(values.reduce(operations.sum, 0));        // 6
console.log(values.reduce(operations.difference, 0)); // -6
console.log(values.reduce(operations.product, 1));    // 6
console.log(values.reduce(operations.quotient, 1));   // 0.167  
 .as-console-wrapper { top: 0; max-height: 100% !important; }