Rozwiązanie Codewars - Funkcje wzajemnie zagnieżdżone [zamknięte]

11

Szukałem rozwiązania zagadki na kodewars i nie rozumiem, dlaczego to działa. Jak działa minus ()?

function makeNum(num, func) {
    if (func === undefined) {
        return num;
    } else {
        return func(num);
    }
}

function three(func) {
    return makeNum(3, func);
}

function eight(func) {
    return makeNum(8, func);
}

function minus(right) {
    return function(left) {
        return left - right;
    };
}

console.log(eight(minus(three()))); // will log out 5

TypeleveN
źródło
Oto podobne pytanie z nieco innym podejściem, które może rzucić nieco światła na to, jak to działa
Nick Parsons,
1
Głosowałem za zamknięciem tego po nieudanej próbie przeglądu: nie było dla mnie oczywiste, czego nie rozumiesz. Byłoby lepiej, gdyby był edytowany w celu wyjaśnienia, dlaczego Twoim zdaniem minus nie powinien działać.
GS - Przeproś Monikę

Odpowiedzi:

8

To trochę skomplikowane. :-)

console.log(eight(minus(three()))); jest uruchamiany od wewnątrz, więc prześledźmy to:

  • three()- dzwoni makeNum(3, undefined)i zwraca to, co zwraca. makeNum(3, undefined)zwraca 3, więc to jest wartość zwracana.
  • minus(3)- połączenia minus, przekazując 3jako right. minuszwraca nową funkcję, która się zamyka right.
  • eight(...)- wywołuje makeNum(8, fnFromMinus)gdzie fnFromMinusjest funkcja, która została zwrócona minus(3). makeNum(8, fnFromMinus)robi fnFromMinus, przechodząc 8jako left. fnFromMinuszwraca wynik left - right(należy pamiętać, że rightto 3, fnFromMinuszamknęła się nad nim).

Ponieważ 8 - 3jest 5to wynik końcowy 5, który console.logpowraca.

Oto wersja instrumentalna:

TJ Crowder
źródło
2

Nie jest to wcale takie skomplikowane, jeśli przejdziesz przez to krok po kroku. Pracujmy od wewnątrz. Powołanie:

three()

bez parametru oznacza, że ​​przekazujesz niezdefiniowaną wartość jako func. To jest tak samo jak powiedzenie:

makeNum(3, undefined)

Gdy makeNum widzi, że func jest niezdefiniowany, zwraca num, czyli 3.

Więc zredukowaliśmy to do:

eight(minus(3))

Zobaczmy teraz, jak to zrobić

minus(3)

ocenia. minus widzi, że podany parametr to 3, więc zwraca funkcję, która może zaakceptować parametr „left” i odjąć 3, które już podaliśmy. NIE wykonuje się. Po prostu tam siedzi i czeka na wywołanie z parametrem „left”, aby mógł odjąć 3 od niego.

Więc zredukowaliśmy to do:

eight(function(left){
    return left - 3;
})

Zobaczmy teraz, jak to ocenia. osiem jest wywoływane z parametrem func będącym tą funkcją:

function(left){
    return left - 3;
}

Następnie przekazuje 8 i tę funkcję do makeNum, gdy mówi:

makeNum(8, func)

makeNum następnie widzi, że func został dostarczony (i dlatego nie jest niezdefiniowany) i zwraca func (num) z powrotem do ósmej funkcji, która jest taka sama jak przekazywanie:

8 - 3

powrót do ósmej funkcji. Osiem funkcji otrzymuje tę wartość, a następnie zwraca ją. Więc zredukowaliśmy to do:

5

który zostaje zalogowany w konsoli.

Aaron Plocharczyk
źródło
0

minuszwraca nową funkcję dla każdego wywołania z przechwyconymi parametrami Po wywołaniu zwróconej funkcji może ona odwoływać się do parametrów przekazywanych podczas wywoływania, oprócz wszelkich przekazywanych do niej parametrów. Jest to jeden ze sposobów curry funkcji w JavaScript.

znak
źródło
0

Ten kod jest przykładem funkcji wyższego rzędu w funkcjonalnych językach programowania, takich jak js. Funkcje Javascript są traktowane jak obiekty i mogą być również przekazywane i zwracane.

Funkcja wyższego rzędu to funkcja, która odbiera funkcję jako argument lub zwraca funkcję jako wynik.

minuszwraca anonimową ( funkcja bez zdefiniowanej nazwy ) funkcję w zasadzie jako:

function(left) {
        return left - 3; //right = 3
    };

Funkcja przekazana do eightjest wywoływana jako, func(8)która następnie daje wynik jako5

bUff23
źródło
0

Inny sposób na to spojrzeć - możesz przepisać tę linię:

console.log(eight(minus(three())));

Tak jak:

const threeResult = three(); // = 3
const minusResult = minus(threeResult); // = a function that subtracts 3
const eightResult = eights(minusResult); // = 5
Andrea Corbellini
źródło