Каррирование с использование apply/bind/call
Помогите пожалуйста пересмотрел уже ролики по каррированию, apply/bind/call, замыканиям. Вроде все понятно но как решить задачу никак не могу додуматься.
Нужно при помощи apply/bind/call написать функцию, которая оборачивает другую функцию так, чтобы результатом была тоже функция, но еще могла принимать заданное кол-во аргументов. Функция принимает на вход другую функцию и число аргументов которое необходимо собрать чтобы передать в функцию которая была передана первым аргументом.
function watchArgs(fn, argumentsLength) {
// Реализовать данную функцию
}
function test1(a, b, c) {
return a + b + c;
}
function test2(a, b, c, d) {
return a + b + c + d;
}
let result;
const t1 = watchArgs(test1, 3);
result = t1(); // все еще функция, необходимо учитывать если аргументы не были переданы
result = t1(1, 2); // все еще функция
result = t1(3); // 6 - результат выполнения функции test1 с аргументами 1, 2 и 3
const t2 = watchArgs(test2, 4);
result = t2(1);
result = t2(1);
result = t2(1, 1); // 4
result = t2(5); // 4
Ответы (1 шт):
Использован только fn.apply(контекст, массив) — Он нужен, чтобы вызвать функцию, передав ей элементы массива или другого итерируемого объекта как аргументы.
function watchArgs(fn, length) {
let args_cache = []; // Хранилище переданных аргументов при всех вызовах.
return function _self() {
if (args_cache.length == length) {
// Набрано достаточно аргументов?
// Вызов исходной функции, и на выход.
return fn.apply(null, args_cache);
}
for (let i = 0; i < arguments.length; i++) {
args_cache.push(arguments[i]);
if (args_cache.length == length) {
return fn.apply(null, args_cache);
}
}
return _self; // Аргументов не хватает, возвращает саму себя.
}
}
/***/
function test1(a, b, c) {
return a + b + c;
}
function test2(a, b, c, d) {
return a + b + c + d;
}
let result;
const t1 = watchArgs(test1, 3);
result = t1();
result = t1(1, 2);
console.log(result = t1(3));
const t2 = watchArgs(test2, 4);
result = t2(1);
result = t2(1);
console.log(result = t2(1, 1)); // 4
console.log(result = t2(5)); // 4
arguments, а заодно и apply (т.к. контекст не сохрняется), можно заменить на ... ( spread )