Закрытие Javascript, возвращающее строку вместо функции - PullRequest
1 голос
/ 08 мая 2019

Я пытаюсь написать простую compose функцию, которая принимает ряд функций и составляет их следующим образом:

compose(func1, func2, func3)(n) === func1(func2(func3(n)))

Я делаю это путем повторения через параметр rest,

var compose = function(...args) {
    return (n) => {
        if (args.length) {
            return args[0](compose(args.slice(1)));
        } else {
            return n;
        }
    };
};

Затем я пытаюсь составить новую функцию, состоящую из ряда других функций,

var plusOneAndTwo = compose((n) => n + 1, (n) => n + 2);
plusOneAndTwo(1);

Вместо возврата 4 я возвращаю тело внутренней, анонимной функции внутри compose как строка,

"(n) => {
        if (args.length) {
            return args[0](compose(args.slice(1)));
        } else {
            return n;
        }
    }1"

Обратите внимание на "1" в конце строки!Я понятия не имею, почему это происходит, и, в частности, я озадачен тем, как к этому добавляется цифра 1.

Любое разъяснение приветствуется, спасибо!

Ответы [ 3 ]

3 голосов
/ 08 мая 2019

Проблема возникает при рекурсивном вызове compose.В частности, вы не передаете ему параметр n (как это было предложено другими выше).Кроме того, вам нужно расширить параметр rest в вызове.

Вы должны использовать что-то вроде:

return args[0](compose(...args.slice(1))(n))

В вашем случае вы просто возвращаете:

return args[0](compose(args.slice(1)));

В вашем примере вы звоните compose((n) => n + 1, (n) => n + 2);.Compose затем возвращает функцию, принимающую n в качестве параметра.В этой функции args.length становится 1 (то есть true-is), args [0] становится (n) => n + 1, а args.slice (1) становится [(n) => n + 2].

Далее вы вызываете эту возвращаемую функцию с параметром n = 1.Поскольку args.length равен 1, оператор if () перейдет в случай if ().В этом случае он вызовет args [0] с аргументом compose(args.slice(1)).

В этом рекурсивном вызове compose (args.slice (1)) вычисляется как функция, принимая n в качестве параметра и то же тело функции.Эта функция затем передается как параметр n аргументам [0] (во внешнем вызове).Напомним, что args [0] в этом сценарии является функцией (n) => n + 1.

Таким образом, вызов в целом эквивалентен:

// returned from the recursive call to compose(args.slice(1))
var n = (n) => {
        if (args.length) {
            return args[0](compose(args.slice(1)));
        } else {
            return n;
        }
}
// applied to arg[0] == (n) => n + 1
return n + 1

Это означает, что код попытается добавить функцию с номером 1. В JavaScript добавление функции и числа приводит кв обоих объектах, приведенных в строку.Преобразование числа в строку тривиально, приведение функции в строку возвращает исходный код функции.Затем эти строки добавляются, чтобы получить возвращаемое значение, которое вы видели: Тело функции в виде строки с 1 в конце.

2 голосов
/ 08 мая 2019

Вам просто нужно вызвать составную функцию:

 return args[0](compose(...args.slice(1))(n));

Или без рекурсии это будет:

 const compose = (...fns) => start => fns.reduceRight((acc, fn) => fn(acc), start);
1 голос
/ 08 мая 2019

Вы можете использовать другой подход, возвращая новую функцию или возвращая последнюю функцию для вызова с аргументами.

const
    compose = (...fns) => fns.length
        ? v => compose(...fns.slice(0, -1))(fns.pop()(v))
        : v => v,
    fn1 = n => n * 5,
    fn2 = n => n + 2,
    fn3 = n => n * 7;

console.log(fn1(fn2(fn3(1))));
console.log(compose(fn1, fn2, fn3)(1));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...