Подтвердить что ты не робот

Javascript указатель функции с аргументом как параметр в функции

Не уверен, правильно ли сформулирован заголовок, или если есть лучший способ сказать это, но я думаю, что все в порядке.

Во всяком случае, я понимаю следующее:

a.b("a", "b", "c", foo);

Где "foo" - это функция, определенная в другом месте, которая не принимает аргументов, просто приведет к выполнению функции a.b() с указанными выше параметрами. Параметр "foo" затем можно вызвать внутри функции a.b() как просто "foo()". Другими словами, я понимаю, что вышеупомянутый вызов использует указатель функции в качестве аргумента в функции a.b в качестве параметра.

Хорошо, теперь вот что я пытаюсь сделать...

Я хочу иметь возможность сделать что-то похожее на предыдущее, за исключением того, что я хочу, чтобы foo имел paramater, переданный в этом аргументе следующим образом:

a.b("a", "b", "c", foo("bar"));

Теперь вот проблема. Это буквально приведет к параметрам "a", "b", "c" и "сильному" результату использования foo ( "bar" ). Я не хочу этого. Я хочу, чтобы foo ( "bar" ) буквально передавался так, чтобы в функции a.b, которая будет выглядеть так (как заголовок):

a.b(first, second, third, fourth);

Может ссылаться и вызывать четвертый параметр как:

fourth();

Даже если "четвертый" имеет в себе аргумент. Я не могу найти способ решить эту проблему, любой совет?

Спасибо!

4b9b3361

Ответ 1

Используйте анонимную функцию для переноса вашего вызова foo.

a.b("a", "b", "c", function() {return foo("bar");});

Если вам нужно сохранить значение this, которое будет указано, вы можете вызвать его с помощью .call. Вы также можете передавать любые аргументы.

a.b("a", "b", "c", function(arg1, arg2) {return foo.call(this, "bar", arg1, arg2);});

И, конечно, функция необязательно должна быть анонимной. Вы также можете использовать именованную функцию.

function bar(arg1, arg2) {
    return foo.call(this, "bar", arg1, arg2);
}
a.b("a", "b", "c", bar);

Ответ 2

Очень просто использовать BIND с функцией

a.b("a", "b", "c", foo.bind(undefined, "bar"));

Поэтому, когда вы вызываете foo() внутри своей функции, он уже имеет первый связанный аргумент. Вы можете использовать больше argumenst, как хотите, используя bind.

Обратите внимание, что bind всегда применяет аргументы функции и помещает их в первую очередь. Если вы хотите применить к этому и использовать это:

    if (!Function.prototype.bindBack) {
    Function.prototype.bindBack = function (_super) {
        if (typeof this !== "function") 
            throw new TypeError("Function.prototype.bindBack - can not by prototyped");

    var additionalArgs = Array.prototype.slice.call(arguments, 1), 
        _this_super = this, 
        _notPrototyped = function () {},
        _ref = function () {
            return _this_super.apply((this instanceof _notPrototyped && _super) ? this : _super, (Array.prototype.slice.call(arguments)).concat(additionalArgs));
        };

    _notPrototyped.prototype = this.prototype;
    _ref.prototype = new _notPrototyped();

    return _ref;
  }
}

function tracer(param1, param2, param3) {
console.log(arguments)
}

function starter(callback) {
callback('starter 01', 'starter 02')
}
// See here!!!
// function starter call 'calback' with just 2 params, to add 3+ params use function.bindBack(undefined, param, param, ...)                
    starter(tracer.bindBack(undefined, 'init value'));

См. пример http://jsfiddle.net/zafod/YxBf9/2/