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

Posted

技术标签:

【中文标题】如何将参数传递给使用 setTimeout 调用的函数?【英文标题】:How can I pass an argument to a function called using setTimeout? 【发布时间】:2012-05-21 07:24:00 【问题描述】:

我想将参数传递给使用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 是您应该永远使用的方法。即使在壁虎浏览器中,方法 2 也已被弃用 - 所以即使不支持 IE,它也几乎是不行的。 【参考方案1】:

我能想到的最佳解决方案是使用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(),总有更好的解决方案。

【讨论】:

还有whatsA.apply(this, [A])whatsA.call(this, A)解决方案。 +1 表示干净的.bind() 解决方案。 @VisionN:这些版本需要自调用函数来避免关闭变量。 你也可以安全地通过窗口 - 或者null,恕我直言,更干净。 好主意,谢谢。请注意 .bind 是一个 jQuery 函数,而不是普通的 javascript(对吗?) @Mark: Nope,它是... function 类型上的标准函数。【参考方案2】:

你可以使用闭包:

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

【讨论】:

【参考方案3】:

在你的三种方法中:

选项 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); 

【讨论】:

以上是关于如何将参数传递给使用 setTimeout 调用的函数?的主要内容,如果未能解决你的问题,请参考以下文章

Promises,将附加参数传递给 then 链

如何将参数传递给使用 Heroku Scheduler 调用的 rake 任务?

如何将参数传递给无服务器调用本地

如何将附加参数传递给 jQuery DataTable ajax 调用?

如何将参数传递给使用 libevent 创建的事件函数?

如何将参数传递给使用 ...mapActions(...) 映射的函数?