Показать сообщение отдельно
  #6 (permalink)  
Старый 17.06.2019, 09:37
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,005

Задача убойная На собеседовании облажаться с ней - как нефиг делать.

var curryN = (function() {
    function bind(n, arg, f) {
        return (n < 1) ? function() {
            var a = arguments;
            return f.apply(this, a.length ? arg.concat.apply(arg, a) : arg);
        } : function(a) {
            return bind(n - 1, arg.concat(a), f);
        }
    }

    return function curryN(n, f) {
        return (typeof n !== 'number' || n < 1) ? f : bind(n, [], f);
    };
})();

function func() {
    console.log(`this = ${this},  args = ${[].join.call(arguments, ', ')}`);
}

var c0func = curryN(0, func);
c0func('a0', 'b');

var c3func = curryN(3, func);
c3func('A')('B')('C')();
var c3func2 = c3func('A')('B');
c3func2('C1')(5555);
c3func2('C2').call('th', 'D', 'E');
c3func2('C3').call('th2');

var c2func = curryN(2, func);
c2func('aa')('bb')();

c3func2('__').call('th4', 5555);


Суть задачи, как я понял: есть функция f, которая может при вызове получить M параметров и с ними что-то сделать.
Например, f(1, 2, 3, 4, 5); - 5 параметров передали.

curryN(N, f) должна создать функцию cf, которая сначала по одному биндит первые N аргументов, потом результат можно вызвать с M-N оставшимися:
cf = curryN(3, f);
cf(1)(2)(3)(4, 5);

Более того, все "промежуточные" результаты - cf(1), cf(1)(2) и т.д. - можно использовать многоразово. Потому arg (накопленные аргументы) должен быть иммутабельным, никаких push и прочих сплайсов.

В идеале при этом конечном вызове надо уметь передать this в функцию f, что я и сделал.
Т.е. чтобы так можно было: cf(1)(2)(3).call(obj, 4, 5); что эквивалентно f.call(obj, 1, 2, 3, 4, 5);

Последний раз редактировалось Alexandroppolus, 17.06.2019 в 10:01.
Ответить с цитированием