假设我有以下功能。
var func = function(a, b, c) {
console.log(a);
console.log(b);
console.log(c);
}
我想要做的是通过在数组中提供它的参数来调用它:
func.apply(null, [1, 2, 3]);
按预期工作。现在,如果我想要异步调用该函数,例如使用setTimeout,我该怎么做?我尝试了以下方法:
setTimeout(func.bind.apply(null, [null, 1, 2, 3]), 1000);
但它给了我一个错误:
TypeError:必须在函数上调用Bind
有优雅的方法吗?
答案 0 :(得分:3)
有很多方法可以做到这一点。
setTimeout
额外参数您是否知道可以像setTimeout
那样传递call
个额外参数?
setTimeout(func, 1000, 1, 2, 3);
但是假设你有一个参数数组:
setTimeout(func, 1000, [1, 2, 3]); // This will not work
所以你需要做以下事情:
setTimeout(function (args) {
return func.apply(this, args);
}, 1000, [1, 2, 3]);
不幸的是,这在旧版本的Internet Explorer中无法使用。但是你可以随时这样做:
function applyAsync(f, ms, args) {
return setTimeout(function () {
return f.apply(this, args);
}, ms);
}
您可以按如下方式调用它:
applyAsync(func, 1000, [1, 2, 3]);
在我看来,这是最干净,最快的解决方案。但是,如果你想要一个更聪明的解决方案,那么:
bindable
,callable
和appliable
我在JavaScript中最喜欢的功能:
var bind = Function.prototype.bind;
var call = Function.prototype.call;
var apply = Function.prototype.apply;
var bindable = bind.bind(bind);
var callable = bindable(call);
var appliable = bindable(apply);
我不会详细解释它是如何运作的,但这是你需要知道的:
bindable
函数接受函数f
并返回等效于f.bind
的函数; f.bind
部分适用于任何其他参数。callable
函数接受函数f
并返回等效于f.call
的函数; f.call
部分适用于任何其他参数。appliable
函数接受函数f
并返回等效于f.apply
的函数; f.apply
部分适用于任何其他参数。您正在寻找的功能是appliable
:
setTimeout(appliable(func, null, [1, 2, 3]), 1000);
这样聪明而优雅。
答案 1 :(得分:2)
你要么
Function.apply.bind(func, null, [1, 2, 3])
或
Function.bind.apply(func, [null, 1, 2, 3])
目前,您正在bind
上应用null
,而不是func
,这会引发错误。
您可以使用.apply
或.bind
,而不是访问Function
上的Function.prototype
/ func
。
答案 2 :(得分:1)
您可以将参数传递给Function.prototype.bind
本身,就像这样
setTimeout(func.bind(null, 1, 2, 3), 1000);
你得到的错误是因为bind
只能对一个函数对象起作用,所以apply
的第一个参数应该是实际的函数对象,就像这样
setTimeout(func.bind.apply(func, [null, 1, 2, 3]), 1000);
答案 3 :(得分:1)
您可以通过这种方式应用Function.prototype.bind
,它只需要您将null传递给数组的第一个元素,您应该没问题。
var myFun = function (a,b,c) {
console.log(a,b,c);
}, myFunBound;
myFunBound = Function.prototype.bind.apply(myFun, [null, 1,2,3]);
setTimeout(myFunBound, 1000);