переменные каррирования
Поскольку «замыкание» - это просто способ сказать, что функция всегда сохраняет свою первоначальную область видимости переменной, есть много способов воспользоваться этим.
Кажется, что людям нравится карри.
Создание манипуляторов со значением карри
Здесь я создал функцию curry
, которая будет возвращать функцию, которая будет использоваться для генерации новых функций, которые работают с исходным значением карри.
function curry() {
var args = Array.prototype.slice.call(arguments);
return function(fn) {
return function() {
var args2 = Array.prototype.slice.call(arguments);
return fn.apply(this,args.concat(args2));
};
};
}
Создание функции, которая карри строки
Так что, если я хочу создать функции для работы со строкой, я мог бы карри строку ...
var workWithName = curry("Bubba");
... и использовать возвращаемую функцию для создания новых функций, которые работают с заданной строкой различными способами.
Создать функцию, которая помещает строку карри в предложение
Здесь я создаю talkToName
функцию, которая будет включать имя в различные предложения на основе переданных аргументов ...
var talkToName = workWithName(function(curried_str, before, after) {
return before + curried_str + after;
});
Так что теперь у меня есть функция talkToName
, которая принимает 2 строки, которые обертывают строку карри.
talkToName("Hello there ", ". How are you?"); // "Hello there Bubba. How are you?"
talkToName("", " is really super awesome."); // "Bubba is really super awesome."
Обратите внимание , что я передаю два аргумента в функцию talkToName
, но функция, переданная workWithName
, принимает 3 аргумента.
Первый аргумент передается функцией, которую мы создали из workWithName()
, и два аргумента, которые мы передаем talkToName
, добавляются после исходного аргумента карри.
Создание функции приращения символов строки карри
Здесь я создаю совершенно другую функцию, используя оригинальную функцию workWithName
, которая будет принимать строку «Bubba» и возвращать строку с буквами, увеличенными на заданное значение ...
var incrementName = workWithName(function(curried_str, n) {
var ret = '';
for(var i = 0; i < curried_str.length; i++) {
ret += String.fromCharCode(curried_str[i].charCodeAt() + n);
}
return ret;
});
Итак, я передаю моей новой функции incrementName
число, которое увеличивает буквы в имени и возвращает новую строку ...
incrementName(3); // "Exeed"
incrementName(8); // "J}jji"
incrementName(0); // "Bubba"
Итак, вы можете видеть, что мы дали curry()
значение, и оно вернуло нам функцию, которую можно использовать для создания новых функций, которые работают с исходным значением.
Еще раз обратите внимание , что я передаю один аргумент функции incrementName
, но функция, переданная workWithName
, принимает 2 аргумента. Первый аргумент карри.
Другие примеры с номерами
Вот пример, который создает генератор функций, который работает с числами 3
и 5
.
var workWith3And5 = curry(3, 5);
Создание функций, которые делают разные вещи с каррированными числами
Таким образом, используя функцию workWith3And5
, мы создаем новую функцию, которая будет принимать числовой аргумент и возвращать массив сумм чисел карри с указанным числом ...
var addNTo3And5 = workWith3And5(function(x, y, n) {
return [3 + n, 5 + n];
});
addNTo3And5( 8 ); // [11, 13];
addNTo3And5( -4 ); // [-1, 1];
И еще одна, использующая ту же самую функцию workWith3And5
, которая каррирует числа 3
и 5
, которая создает массив массивов 3 x 5, где вложенному массиву присваивается некоторое содержимое ...
var create3By5GridWithData = workWith3And5(function(x, y, data) {
var ret = []
for(var i = 0; i < x; i++) {
ret[i] = [];
for(var j = 0; j < y; j++) {
ret[i][j] = data;
}
}
return ret;
});
create3By5GridWithData( 'content' ); // [Array[5], Array[5], Array[5]]