简体   繁体   English

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

[英]How can I pass an argument to a function called using setTimeout?

I want to pass an argument to a function called using setTimeout . 我想将参数传递给使用setTimeout调用的函数。 I have found these three options: 我找到了这三个选项:

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); }

This shows 2 , undefined , and 1 in Internet Explorer 9. 这在Internet Explorer 9中显示2undefined1

Method 1 : Clearly, I would not like the argument to be changed after passing it (certainly in the case of simple integers). 方法1 :显然,我不希望在传递之后更改参数(当然在简单整数的情况下)。

Method 2 : This would be perfect if only Internet Explorer supported it. 方法2 :如果只有Internet Explorer支持它,这将是完美的。

Method 3 : This seems to be the only choice. 方法3 :这似乎是唯一的选择。 But it seems rather less pretty than the others, passing something to be evaluated rather than a function. 但它看起来并不像其他人那么漂亮,传递的东西要被评估而不是功能。

Is there a better way? 有没有更好的办法?

The best solution I can think of is using bind() : 我能想到的最好的解决方案是使用bind()

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

Because bind() is actually a function invocation, it reads the current A value and returns a function with that value bound as an argument. 因为bind()实际上是一个函数调用,它会读取当前的A值并返回一个函数,该值将该值绑定为参数。 If you find it hard to understand, try this: 如果您发现难以理解,请尝试以下方法:

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

Note that this is kind of a lie here - you can safely pass window as well. 请注意, this是一种谎言 - 您也可以安全地传递window


The first method is also acceptable, it just needs to be slightly improved: 第一种方法也可以接受,只需稍加改进:

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

What you are observing is actually a feature, not a bug. 你观察到的实际上是一个特征,而不是一个bug。 You are passing a closure to setTimeout() referencing local variable. 您正在将闭包传递给引用局部变量的setTimeout() JavaScript is clever enough to delay access to that variable up to the moment when the function is actually called. JavaScript非常聪明,可以在实际调用函数之前延迟对该变量的访问。 And since you have modified the variable, you see the most recent version. 由于您已修改变量,因此您会看到最新版本。


The second method is deprecated 第二种方法已弃用 won't work in any browser 将无法在任何浏览器中工作 .


Third method is terrible, avoid passing string to setTimeout() , there is always a better solution. 第三种方法很糟糕,避免将字符串传递给setTimeout() ,总有一种更好的解决方案。

You could use closure: 你可以使用闭包:

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

Of your three methods: 在你的三种方法中:

Option 1: 选项1:

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

This one works everywhere and is simple. 这个适用于所有地方并且很简单。 It's what I would recommend unless the variable A might change before the setTimeout function is called. 这是我建议的,除非在调用setTimeout函数之前变量A可能会改变。 If you need to freeze the value of A , then see my option 4 below. 如果您需要冻结A的值,请参阅下面的选项4。


Option 2: 选项2:

setTimeout(whatsA, 100, A);

This only works in some browsers. 这仅适用于某些浏览器。 Not recommended. 不建议。


Option 3: 选项3:

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

This is never recommended. 永远不建议这样做。 Constructing code as a string and then evaluating it later is almost never the best solution. 将代码构造为字符串然后再对其进行评估几乎不是最佳解决方案。


I would recommend Option 4 : 我建议选项4

To freeze the value of A , you can create a closure using a self executing function: 要冻结A的值,可以使用自执行函数创建闭包:

A = 1;

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM