6

我想将一个参数传递给一个名为 using 的函数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 中显示2undefined和。1

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

方法二:如果只有 Internet Explorer 支持就完美了。

方法3:这似乎是唯一的选择。但它似乎不如其他漂亮,传递要评估的东西而不是函数。

有没有更好的办法?

4

3 回答 3

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(),总有更好的解决方案。

于 2012-05-13T14:58:19.013 回答
4

你可以使用闭包:

setTimeout((function(A){
               return function(){
                   whatsA(A);
               }; 
            })(A), 100);
于 2012-05-13T14:59:06.277 回答
0

在您的三种方法中:

选项1:

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

这个适用于任何地方并且很简单。这是我推荐的,除非变量A在调用 setTimeout 函数之前可能会发生变化。如果您需要冻结 的值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); }
于 2012-05-13T15:10:53.730 回答