Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/414.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将参数传递给使用setTimeout调用的函数?_Javascript_Closures_Scope_Settimeout - Fatal编程技术网

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

Javascript 如何将参数传递给使用setTimeout调用的函数?,javascript,closures,scope,settimeout,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 + ')',

我想将一个参数传递给一个使用
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中的
2
未定义的
1

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

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

方法3:这似乎是唯一的选择。但它似乎不如其他函数漂亮,它传递的是要求值的内容,而不是函数


有更好的方法吗?

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

因为
bind()
实际上是一个函数调用,所以它读取当前的
a
值,并返回一个将该值绑定为参数的函数。如果您觉得难以理解,请尝试以下方法:

var newFun = whatsA.bind(this, 42);
newFun()
请注意,
这个
有点像谎言-您也可以安全地通过
窗口


第一种方法也是可以接受的,只需要稍微改进一下:

A = 1;
var tmpA = A;
setTimeout(function() { whatsA(tmpA); }, 100);
您所观察到的实际上是一个特性,而不是一个bug。您正在向引用局部变量的
setTimeout()
传递一个闭包。JavaScript足够聪明,可以将对该变量的访问延迟到函数实际被调用时。由于您已经修改了变量,因此可以看到最新的版本


第二种方法不推荐在任何浏览器中使用


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

您可以使用闭包:

setTimeout((function(A){
               return function(){
                   whatsA(A);
               }; 
            })(A), 100);
在你的三种方法中:

选项1:

setTimeout(函数(){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); }

还有
whatsA.apply(this,[A])
whatsA.call(this,A)
解决方案。+1表示干净的
.bind()
解决方案@VisionN:这些版本需要自调用功能,以避免关闭变量。您也可以安全地传递窗口-或者
null
,这更干净。好主意,谢谢。需要注意的是.bind是一个jQuery函数,而不是普通的javascript(对吗?@Mark:),它是<代码>函数
类型。方法3是您永远不应该使用的方法。方法2甚至在gecko浏览器中也被弃用,因此即使不支持IE,也几乎是不可能的。
A = 1;

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

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