function createMathOperation(operator) {
console.info(operator); //(augend, addend) => augend + addend
return (value, other) => {
return operator(value, other)
}
}
const add = createMathOperation((augend, addend) => augend + addend)
add(1,2)//3
Я нашел приведенное выше определение функции из lodash. Я пытаюсь понять это, но безуспешно.
Прямо внутри createMathOperation я пытаюсь зарегистрировать operator, и это значение
(augend, addend) => augend + addend
Я предполагаю, что value и other - это 1 и 2, но как?
И как return operator(value, other) работает, когда operator - это (augend, addend) => augend + addend
Может ли кто-нибудь преобразовать его в более удобочитаемую форму для лучшего понимания?
Добро пожаловать в функции высшего порядка. Вы близки к точке невозврата, будьте осторожны: как только вы войдете намного дальше, вы не сможете вернуться.
@JaredSmith, - говорит он с широкой ухмылкой ...
@ user633183 да, публикация вопроса означает, что, вероятно, уже слишком поздно. Перейдем к функторам!



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


createMathOperation возвращает функцию, которая складывает два числа. Вот более читаемая версия:
function createMathOperation(fn) {
console.info(fn);
return function(value, other){
return fn(value, other);
};
}
const add = createMathOperation(function (augend, addend) {
return augend + addend;
});
add(1,2)//3
Я переименовал «оператор» в «fn», чтобы сделать его менее запутанным (подсветка синтаксиса почему-то окрасила его в синий цвет).
Это суть функционального программирования, которое вы можете передать в функцию, вернуть функцию и вызвать функцию, которую вы получили в качестве параметра:
function createMathOperation(operator) {
console.info(operator); // This is a the function that performs the computation
// We return a new function (using arrow syntax) that receives 2 arguments and will call the original operator we passed in to createMathOperation
// The code inside this function is not executed here, the function is not invoked.
// The caller can take the returned function and executed 0-n times as they wish.
return (value, other) => {
// when we invoke add this is the code that gets called and the arguments we pass to add end up in value and other
console.info("Getting ready to compute " + value + " operator " + other);
return operator(value, other) // since operator is a function we just invoke it as we would any other function with the two arguments we got from whoever called us.
}
}
// add will contain the wrapped function that has our extra console.info
const add = createMathOperation((augend, addend) => augend + addend)
// The 'Getting ready ...' text has not been printed yet, nobody invoked the function that was returned yet, the next line will do so.
console.info(add(1,2))
// will output:
// Getting ready to compute 1 operator 2
// 3
Примечание о => - это просто синтаксический сахар по сравнению с выражением function, он имеет дополнительную семантику вокруг this, но для этого примера (augend, addend) => augend + addend эквивалентен function (augend, addend){ return augend + addend; }
В ваших комментариях We return a new function (using arrow syntax) that receives 2 arguments. Что означает, что return (value,other) => {...} по-прежнему является всего лишь объявлением функции, верно?
Ага, это выражение функции, оно представляет новую функцию, которая будет возвращена. Код внутри не будет выполнен, пока вы не вызовете add.
Ваш код на старом добром JS будет выглядеть так:
var createMathOperation = function(operator) {
// operator is scope-locked within this operation wrapper
console.info('operator:', operator);
return function(value, other) {
// The wrapper returns an anonymous function that acts as a call-wrapper
// for your original function
console.info('value:', value);
console.info('other:', other);
return operator(value, other)
}
}
var add = createMathOperation(function(augend, addend) {
// This is what is being called at line 9 - return operator(value, other)
return augend + addend;
});
console.info('result 1+2:', add(1,2));В общем, я не вижу во всем этом особого смысла, вы можете просто сделать const add = (a, v) => a + v; и получить тот же результат.
Исходное тело createMathOperation имеет гораздо более длинную форму, которая позволяет преобразовывать и обрабатывать все виды значений undefined. Я удалил их, потому что они просто шум для моей цели
Понятно, в этом случае обертка имеет смысл.
Суть в том, что в JS-функциях есть объекты, и эти объекты могут передаваться точно так же, как и любой другой объект первого класса.