Может ли кто-нибудь помочь мне понять этот кусок кода в 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
функция, предоставляя доступные аргументы в правильном порядке.