Как передать ссылку на функцию с параметрами?

Возможный дубликат:
Как я могу предварительно задать аргументы в вызове функции JavaScript? (Приложение с частичной функцией)

Мне нужно передать ссылку на функцию с заданным набором параметров.

Вот пример передачи ссылочных параметров без:

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

Теперь мне нужно передать ту же функцию f, но на этот раз мне нужно будет передать параметры в ссылку. Теперь я могу сделать это с анонимной функцией и вызвать функцию f с параметрами внутри вновь созданной функции, например:

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

Но мой вопрос: Есть ли способ передать прямую ссылку на функцию f с параметрами на fr, но без включения ее в анонимную функцию?

Что мне нужно назначить fr, чтобы сделать его invokable без параметров (fr()), так что f (1,2,3) выполняется при вызове fr?

[ОБНОВЛЕНИЕ] Я последовал за Джейсоном Бантингом на здесь о частичной функции и функции JavaScript, которую он публикует, есть именно то, что я искал. Вот решение:

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);
  };
}

Ответ 1

То, что вам нужно, называется приложение частичной функции.

Не обманывайтесь теми, кто не понимает тонкой разницы между этим и карри, они разные.

Приложение с частичной функцией может использоваться для реализации, но не выполняется. Вот цитата из сообщение в блоге о разнице:

Если частичное приложение принимает функцию и из нее строит функцию, которая принимает меньше аргументов, currying строит функции, которые принимают несколько аргументов по составу функций, каждый из которых принимает один аргумент.

Это уже ответили на этот вопрос для ответа: Как я могу предварительно задать аргументы в вызове функции JavaScript?

Пример:

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

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

Снова посмотрим на этот вопрос для деталей.

Ответ 2

Вы также можете перегрузить прототип функции:

// 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
*/

Ответ 3

Следующее эквивалентно вашему второму коду:

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

var fr = f;

fr(pars);

Если вы хотите передать ссылку на функцию какой-либо другой функции, вы можете сделать что-то вроде этого:

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

Вы почти наверняка лучше используете фреймворк для такого рода вещей.