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();
Даже если "четвертый" имеет в себе аргумент. Я не могу найти способ решить эту проблему, любой совет?
Спасибо!
Ответы
Ответ 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/