如何将参数传递给使用setTimeout调用的函数?

时间:2012-05-13 14:52:24

标签: javascript closures scope settimeout

我想将参数传递给使用setTimeout调用的函数。我找到了这三个选项:

A = 1;
// Method 1: closure things
setTimeout(function() { whatsA(A); }, 100);
// Method 2: third argument (same result with [A])
setTimeout(whatsA, 100, A);
// Method 3: eval
setTimeout('whatsA(' + A + ')', 100);
A = 2;
function whatsA(X) { console.log(X); }

这会在Internet Explorer 9中显示2undefined1

方法1 :很明显,我不希望在传递之后更改参数(当然在简单整数的情况下)。

方法2 :如果只有Internet Explorer支持,这将是完美的。

方法3 :这似乎是唯一的选择。但它看起来并不像其他人那么漂亮,传递的东西要被评估而不是功能。

有更好的方法吗?

3 个答案:

答案 0 :(得分:7)

我能想到的最佳解决方案是使用bind()

A = 1;
setTimeout(whatsA.bind(this, A), 100);

因为bind()实际上是一个函数调用,它会读取当前的A值并返回一个函数,该值将该值绑定为参数。如果你觉得很难理解,试试这个:

var newFun = whatsA.bind(this, 42);
newFun()

请注意this在这里有点谎言 - 您也可以放心地传递window


第一种方法也可以接受,只需稍加改进:

A = 1;
var tmpA = A;
setTimeout(function() { whatsA(tmpA); }, 100);

您所观察到的实际上是一个功能,而不是一个错误。您正在将一个闭包传递给setTimeout()引用局部变量。 JavaScript非常聪明,可以在实际调用函数之前延迟对该变量的访问。由于您修改了变量,因此您会看到最新版本。


第二种方法已弃用不适用于任何浏览器


第三种方法很糟糕,避免将字符串传递给setTimeout(),总会有更好的解决方案。

答案 1 :(得分:4)

你可以使用闭包:

setTimeout((function(A){
               return function(){
                   whatsA(A);
               }; 
            })(A), 100);

答案 2 :(得分:0)

你的三种方法:

选项1:

setTimeout(function() { whatsA(A); }, 100);

这个适用于所有地方并且很简单。这是我建议的,除非在调用setTimeout函数之前变量A可能会发生变化。如果您需要冻结A的值,请参阅下面的选项4.


选项2:

setTimeout(whatsA, 100, A);

这仅适用于某些浏览器。不推荐。


选项3:

setTimeout('whatsA(' + A + ')', 100);

永远不建议这样做。将代码构造为字符串然后再进行评估几乎不是最佳解决方案。


我建议选项4

要冻结A的值,可以使用自执行函数创建闭包:

A = 1;

function(A) {
    setTimeout(function() {whatsA(A);}, 100);
}(A);

A = 2;
function whatsA(X) { console.log(X); }