Pergunta

Duplicate possíveis:
Como posso pré-set argumentos na chamada de função JavaScript? (Aplicação função parcial)

Eu preciso capaz de passar uma referência a uma função com um determinado conjunto de parâmetros .

Aqui está um exemplo de passar uma referência sem parâmetros :

var f = function () {
    //Some logic here...
};

var fr = f; //Here I am passing a reference to function 'f', without parameters
fr(); //the 'f' function is invoked, without parameters

Agora, o que eu preciso fazer é passar a mesma função f, mas desta vez eu precisaria passar parâmetros para a referência. Agora, eu posso fazê-lo com uma função anônima e invocar a função f com parâmetros dentro da função recém-criada, como tal:

var f = function () {
        //Some logic here...
    };

var fr = function (pars) {
    f(pars);
}; //Here I am creating an anonymous function, and invoking f inside it

fr({p : 'a parameter'}); //Invoking the fr function, that will later invoke the f function with parameters

Mas a minha pergunta é, Existe uma maneira de passar uma referência direta à função f Com parâmetros para fr, mas sem colocar-lo em uma função anônima?

O que eu preciso para atribuir a fr para torná-lo invokable sem parâmetros (fr()), de modo que f (1,2,3) é executado quando fr é invocado?

[UPDATE] Segui Jason Bunting 's para aqui sobre os função parcial e a função JavaScript ele posts não é exatamente o que eu estava procurando. Aqui está a solução:

function partial(func /*, 0..n args */) {
  var args = Array.prototype.slice.call(arguments).splice(1);
  return function() {
    var allArguments = args.concat(Array.prototype.slice.call(arguments));
    return func.apply(this, allArguments);
  };
}
Foi útil?

Solução

O que você está depois é chamado aplicação de função parcial .

Não se deixe enganar por aqueles que não entendem a sutil diferença entre isso e currying, eles são diferente.

aplicação de função parcial pode ser usado para implementar, mas não currying. Aqui está uma citação de um post sobre a diferença :

Se a aplicação parcial assume uma função e a partir dele constrói uma função que leva menos argumentos, curtimenta constrói funções que têm múltiplos argumentos por composição de funções que cada um único argumento.

Esta já foi respondida, consulte esta pergunta pela sua resposta: Como posso argumentos pré-definido em chamada de função JavaScript

Exemplo:

var fr = partial(f, 1, 2, 3);

// now, when you invoke fr() it will invoke f(1,2,3)
fr();

Novamente, veja essa pergunta para os detalhes.

Outras dicas

Você também pode sobrecarregar o protótipo Função:

// partially applies the specified arguments to a function, returning a new function
Function.prototype.curry = function( ) {
    var func = this;
    var slice = Array.prototype.slice;
    var appliedArgs = slice.call( arguments, 0 );

    return function( ) {
        var leftoverArgs = slice.call( arguments, 0 );
        return func.apply( this, appliedArgs.concat( leftoverArgs ) );
    };
};

// can do other fancy things:

// flips the first two arguments of a function
Function.prototype.flip = function( ) {
    var func = this;
    return function( ) {
        var first = arguments[0];
        var second = arguments[1];
        var rest = Array.prototype.slice.call( arguments, 2 );
        var newArgs = [second, first].concat( rest );

        return func.apply( this, newArgs );
    };
};

/*
e.g.

var foo = function( a, b, c, d ) { console.log( a, b, c, d ); }
var iAmA = foo.curry( "I", "am", "a" );
iAmA( "Donkey" );
-> I am a Donkey

var bah = foo.flip( );
bah( 1, 2, 3, 4 );
-> 2 1 3 4
*/

A seguir é equivalente à sua segunda bloco de código:

var f = function () {
        //Some logic here...
    };

var fr = f;

fr(pars);

Se você quer realmente passar uma referência a uma função para outra função, você pode fazer algo como isto:

function fiz(x, y, z) {
    return x + y + z;
}

// elsewhere...

function foo(fn, p, q, r) {
    return function () {
        return fn(p, q, r);
    }
}

// finally...

f = foo(fiz, 1, 2, 3);
f(); // returns 6

Você é quase certamente melhor fora de usar uma estrutura para esse tipo de coisa, no entanto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top