Может ли кто-нибудь помочь мне понять этот кусок кода в Javascript?

var curryIt = function(uncurried) {
  var parameters = Array.prototype.slice.call(arguments, 1);
  return function() {
    return uncurried.apply(this, parameters.concat(
      Array.prototype.slice.call(arguments, 0)
    ));
  };
};
var greeter = function(greeting, separator, emphasis, name) {
  console.log(greeting + separator + name + emphasis);
};
var greetHello = curryIt(greeter, "Hello", ", ", ".");
greetHello("Heidi"); //"Hello, Heidi."
greetHello("Eddie"); //"Hello, Eddie."

Я получаю общую картину происходящего, но я не понимаю, что происходит в функции curryIt.

2 ответа

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

Например, пусть у нас есть следующая функция:

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

Если мы позвоним sum как показано ниже:

sum(3,4)

arguments будет содержать два пункта 3 и 4. (На самом деле, вы можете позвонить sum с 3, 4 или более аргументами. Все эти значения будут содержаться в аргументах).

Ключевым словом в приведенном выше утверждении является массив, подобный структуре данных. arguments это не массив. Таким образом, вы не можете иметь доступ к методам массива (push, shift, slice и т. Д.)

Что значит slice ?

Метод slice() возвращает поверхностную копию части массива в новый объект массива, выбранный от начала до конца (конец не включен). Исходный массив не будет изменен.

Для получения дополнительной информации, пожалуйста, посмотрите здесь.

Так что если вы хотите apply нарезать arguments Вы могли бы сделать?

поскольку arguments это не массив, (arguments instanceof Array возвращает false), вы не можете сделать это, как показано ниже:

var a = ["zero", "one", "two", "three"];
var sliced = a.slice(1,3);

Но вы не можете сделать это, как показано ниже:

Array.prototype.slice.call(arguments, 1);

Что звонит?

Метод call() вызывает функцию с заданным значением this и аргументами, предоставляемыми индивидуально.

Для получения дополнительной информации, пожалуйста, посмотрите здесь.

Итак, по сути, следующая строка кода

Array.prototype.slice.call(arguments, 1);

вызывает функцию под названием slice на arguments объекты, передающие 1 в качестве аргумента. Таким образом, вы получите массив со всеми аргументами, кроме первого.

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

Давайте сделаем код более функциональным.

var curryIt = (uncurried,...args) => name => uncurried(...args,name),
    greeter = (greeting, separator, emphasis, name) => console.log(greeting + separator + name + emphasis),
 greetHello = curryIt(greeter, "Hello", ", ", ".");
 
greetHello("Heidi"); //"Hello, Heidi."
greetHello("Eddie"); //"Hello, Eddie."

curryIt Функция принимает несколько аргументов, первый из которых называется функцией uncurried остальные аргументы собраны в args массив с помощью оператора отдыха (...) из ES6.

Затем мы возвращаем функцию, которая принимает один аргумент name и использует параметры, переданные его родительской функции args массив. Итак, сейчас args массив и его элементы закрыты. Возвращенная функция вызовет переданный uncurried функция, предоставляя доступные аргументы в правильном порядке.

Другие вопросы по тегам