#javascript #function #partial
#javascript #функция #частичный
Вопрос:
function asArray(quasiArray, start) {
var result = [];
for (var i = (start || 0); i < quasiArray.length; i )
result.push(quasiArray[i]);
return resu<
}
function partial(func) {
var fixedArgs = asArray(arguments, 1);
return function(){
return func.apply(null, fixedArgs.concat(asArray(arguments)));
};
}
function compose(func1, func2) {
return function() {
return func1(func2.apply(null, arguments));
};
}
var isUndefined = partial(op["==="], undefined);
var isDefined = compose(op["!"], isUndefined);
show(isDefined(Math.PI));
show(isDefined(Math.PIE));
Почему функция compose не может просто возвращать:
func1(func2);
и выдайте правильный вывод. Я думал, что частичная функция, которая хранится в переменной isUndefined, уже возвращает func.apply(null, [исправлено, аргументы])
var op = {
" ": function(a, b){return a b;},
"==": function(a, b){return a == b;},
"===": function(a, b){return a === b;},
"!": function(a){return !a;}
/* and so on */
};
Комментарии:
1. где
op
объявлено? Можете ли вы добавить это в?
Ответ №1:
Оба partial
и compose
являются функциями более высокого порядка.
isUndefined
вернет функцию, которая при вызове вызовет первоначально переданную функцию с исходными аргументами плюс любые новые аргументы, переданные при вызове.
Чтобы ответить на ваш вопрос, вы бы вызывали apply
функцию, возвращаемую из partial
, которая, в свою очередь, вызовет apply
функцию, первоначально переданную partial
.
Вы хотите compose
вернуть функцию, которая при вызове вернет результат вызова первой функции, переданной второй функции в качестве аргумента (при передаче второй функции аргументы, переданные в compose
вызов). Если compose
возвращено func1(func2)
, то вы бы присвоили результат вызова переменной isDefined
.
Редактировать:
Теперь, когда у нас есть op
, давайте попробуем разложить это:
var isUndefined = partial(op["==="], undefined);
это эквивалентно
var isUndefined = partial(function(a, b){return a === b;}, undefined);
isUndefined
назначается функция, которая при вызове будет вызывать функцию, переданную в качестве первого аргумента partial
, передавая undefined
в качестве первого аргумента для этого вызова функции, за которым следуют аргументы, переданные функции isUndefined
, т.е.
partial(function(a, b){return a === b;}, undefined /* this will become 'a' when isUndefined is invoked */)(argumentForisUndefined /* this will become 'b' when isUndefined is invoked */);
isDefined
составляется isUndefined
с другой функцией, которая отрицает результат isUndefined
.
var isDefined = compose(op["!"], isUndefined);
эквивалентно
var isDefined = compose(function(a){return !a;}, isUndefined);
что эквивалентно (переименованные переменные для ясности)
var isDefined = compose(
function(a){return !a;},
partial( /* partial function becomes 'a' passed to first function */
function(b, c) {
return b === c;
},
undefined /* undefined becomes 'b' passed to partial */
)
)(argumentForisDefined /* argumentForisDefined becomes 'c' passed to partial */);
Если мы посмотрим на то, что у нас есть на данный момент, и заменим для удобства чтения, все сводится к функции, которая принимает аргумент и сравнивает его с неопределенным, отрицает результат и возвращает логическое
var isDefined = function (b) { return !undefined === b; }
Комментарии:
1. Хорошо, я думаю, что понимаю свое собственное замешательство. Я был сбит с толку тем, почему function.apply появлялся дважды. Но если функция Compose была просто func1 (func2), аргументы (в данном случае Math. Число ПИ или математика. PIE) никогда не будет передан частичной функции. Я прав?
2. Это верно — compose не вернул бы функциональную композицию из двух функций, которым она была передана изначально, но вернул бы результат их немедленного вызова, так что в любом случае не было бы необходимости передавать дополнительные значения
partial
; это было бы уже вызвано.
Ответ №2:
Итак, давайте просто проанализируем это. Предполагая, что у нас есть эта функция compose:
function compose(func1, func2) {
return func1(func2.apply(null, arguments));
}
Что произойдет, когда вы будете использовать его подобным образом?
a = compose(function(){console.log(1)}, function(){console.log(2)});
Вторая функция будет вызываться немедленно с выводом 2
, и сразу после этого первая функция будет вызываться с выводом 1
. a
будет undefined
, потому что первая функция ничего не возвращает.
То, что вы хотите сделать combine, это вернуть новую функцию, которая объединяет две другие функции и которую вы можете вызывать по желанию.
Выполнение всего вышеописанного в исходной композиции вернет новую функцию, которая при вызове с помощью a()
будет выводить 2
, а затем 1
.