Вызов функции через Apply против прямого вызова из функций Curry - PullRequest
1 голос
/ 26 апреля 2020

Я пытаюсь реализовать функцию каррирования:

function sum(a, b, c) {
console.log('SUM'+JSON.stringify(arguments))
  return a + b + c;
}

var curry= function (func,...n) {
      return function(...args2) {
         //console.log('arg2s'+args2)
        return func.apply(this,n.concat(args2));


  };

}

curry(sum,1,2)(3) //SUM{"0":1,"1":2,"2":3}, O/P:6

Выше дает правильный вывод, но у меня нет необходимости использовать apply.

Итак, если я изменю свою функцию ниже:

var curry= function (func,...n) {
      return function(...args2) {
         //console.log('arg2s'+args2)
        return func(n.concat(args2));


  };

}
curry(sum,1,2)(3) //SUM{"0":[1,2,3]}  O/P:"1,2,3undefinedundefined"

У меня здесь два вопроса:

  1. Почему реализация curry не работает при непосредственном вызове fun c? Почему вывод такой странный? ?

2.Как изменить свою функцию так, чтобы я мог вызывать ее, как показано ниже, и должен возвращать сумму: curry (1) (2) (3) / curry (1,2) (3) / curry (1,2,3) et c вместо того, как я сейчас звоню. Я мог найти некоторые решения в Интернете, но не мог понять.

Пример:

function curry(func) {

  return function curriedFunc(...args) {
    if (args.length >= func.length) {
      return func.apply(this, args);
    } else {
      return function(...args1) {
        return curriedFunc.apply(this, args.concat(args1));
      }
    }
  };

}

Любая помощь будет высоко ценится!

1 Ответ

1 голос
/ 26 апреля 2020

Ваш func принимает три аргумента: a, b и c. Когда вы делаете:

return func(n.concat(args2));

вы передаете его один аргумент, массив. Это эквивалентно:

const arr = n.concat(args2);
return func(arr);

Звучит так, как если бы вы хотели распространить аргументы в вызове func вместо:

return func(...n, ...args2)

С синтаксисом расширения каждый элемент из повторяемого объекта помещается в параметр. Например, если массив n имеет один элемент, он устанавливается как первый аргумент, переданный func, а если args2 имеет 2 элемента, первый устанавливается как второй передаваемый аргумент, а второй устанавливается как передан третий аргумент.

function sum(a, b, c) {
  console.log('SUM' + JSON.stringify(arguments))
  return a + b + c;
}

var curry = function(func, ...n) {
  return function(...args2) {
    return func(...n, ...args2);
  };

}
curry(sum, 1, 2)(3);

Как изменить свою функцию так, чтобы я мог вызывать ее, как показано ниже, и должен возвращать сумму: curry (1) (2) (3) / curry (1,2) (3) / curry (1,2,3) et c

Отслеживайте общее количество аргументов, переданных в замыкании, создавшем first раз функция вызывается. В возвращенной функции pu sh все аргументы массива, а если длина массива равна 3, вернуть сумму, в противном случае вернуть функцию снова:

function sum(a, b, c) {
  return a + b + c;
}

var curry = function(func, ...argsSoFar) {
  const neededArgs = func.length;
  const returnedFn = (...args) => {
    argsSoFar.push(...args);
    if (argsSoFar.length === neededArgs) {
      return func(...argsSoFar);
    } else {
      return returnedFn;
    }
  };
  return returnedFn;
}
console.log(
  curry(sum, 1, 2)(3),
  curry(sum)(1, 2)(3),
  curry(sum)(1)(2, 3),
  curry(sum)(1)(2)(3),
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...