функция позволяющая фиксировать все аргументы
Задача взята с http://dkab.github.io/jasmine-tests/?spec=6
Суть: Написать функцию partialAny которая позволяет фиксировать зафиксировать любые аргументы, пропущенные аргументы обозначаются с помощью undefined: Написала cследующее, но не прошла тестировку, выдаёт следующее "может вызываться несколько раз и результаты во второй раз не зависят от первого" направьте меня как переписать правильно..: function partialAny() { var func = arguments[0]; var masArg = []; var masArg2 = []; var count = 0; for(let k=1; k<arguments.length; k++) { masArg[k-1] = arguments[k]; } return function() { for(let k=0; k<arguments.length; k++) { masArg2[k] = arguments[k]; } for(let z=0; z<masArg.length; z++) { if(masArg[z] === undefined) { masArg[z] = masArg2[count]; count++; } } for(let z=count; z<masArg2.length; z++) { masArg[masArg.length] = masArg2[z]; } return func.apply(this, masArg); } } function test(a, b, c) { return "a=" + a + ", b=" + b + ", c=" + c} var test1_3 = partialAny(test, 1, undefined, 3, undefined); console.log(test1_3(5, 9, 22, "asdasd")); // a=1,b=5,c=3 console.log(test1_3(1, 2, 4, "7")); // должна вывести a=1,b=2,c=3 а выводит a=1,b=5,c=3 (т.е предыдущее значение) |
ami_moor, не знаю правильно ли я понял суть задачи, но:
function test(a, b, c) { return 'a=' + a + ',b=' + b + ',c=' + c; } var _test=partialAny(test,1,undefined,3,undefined); console.log(_test(5, 9, 22, "asdasd")); console.log(_test(1, 2, 4, "7")); function partialAny(callable,_args){ if(!arguments.length) throw new Error('Missing first argument'); var args=[]; for(var i=0;i<arguments.length;i++){ args[i]=arguments[i]; }; callable=args.shift(); if(typeof callable!='function') throw new Error('First argument must be function'); return function(){ var _args=args.slice(0); if(!!arguments.length){ var blanks=[]; for(var i=0;i<_args.length;i++){ if(_args[i]===undefined) blanks.push(i); }; for(i=0;i<arguments.length;i++){ var key=blanks.shift(); if(key!==undefined) _args[key]=arguments[i]; else _args.push(arguments[i]); }; }; return callable.apply(window,_args); }; }; |
function partialAny(fn, ...args) { return (...args2) => { return fn(...args.map(arg => arg === undefined ? args2.shift() : arg), ...args2) } } Принцип, если непонятен синтаксис: 1. Проходимся по массиву аргументов функции partialAny и возвращаем новый массив (Array.map) 2. Сравниваем каждый элемент с undefined 3. Если true, заменяем первым элементом из массива аргументов возвращаемой функции (с удалением, Array.shift) 4. Вызываем переданную функцию fn с аргументами из получившегося массива (пункт 1) аргументов, добавляем в конец оставшиеся аргументы из массива аргументов возвращаемой функции (... - оператор spread) |
Цитата:
|
ami_moor,
function partialAny() { var c = arguments[0], d = [].slice.call(arguments, 1), a; return function() { var e = 0; a = [].slice.call(arguments, 0); a = d.map(function(b) { return void 0 === b ? a[e++] : b }); return c.apply(this, a) } }; function test(a, b, c) { return "a=" + a + ", b=" + b + ", c=" + c} var test1_3 = partialAny(test, 1, undefined, 3, undefined); console.log(test1_3(5, 9, 22, "asdasd")); // a=1,b=5,c=3 console.log(test1_3(1, 2, 4, "7")); // a=1,b=1,c=3 |
ami_moor, Ваша ключевая ошибка в том, что результат возвращаемой функции зависит от переменных, которые хранятся в замыкании и которые Вы изменяете:
1. В возвращаемой функции Вы вызываете func с массивом аргументов masArg, который изменили до этого. Чего делать нельзя, так как при последующем вызове функции массив masArg сохранится в замыкании. Перед изменением masArg сделайте копию массива и работайте с ней. К примеру: let args = masArg.slice() 2. Во вторых, у Вас в замыкании хранится count и в возвращаемой функции эта переменная никак не обновляется. Значит при повторном вызове она будет иметь значение на конец предыдущего вызова функции. Для исправления Вашего кода вынесите объявление masArg2 и count в начало возвращаемой функции. И перед проверкой на undefined сделайте копию masArg и вносите аргументы уже в копию, аргументы из которой потом передадите в func. Ну и конечно, как уже сказал рони, результат второго вызова должен быть не 'a=1, b=2, c=3', а 'a=1, b=1, c=3'. |
Часовой пояс GMT +3, время: 03:24. |