如何将变量传递给匿名函数

ale*_*eyb 6 javascript

我想传递变量setTimeout函数并做一些事情.当我提醒i它的价值时,它显示了我没想到的数字.我做错了什么?我想要从1到8的日志值.

var end=8;
for (var i = 1; i < end; i ++) {
       setTimeout(function (i) {
           console.log(i);   

       }, 800);
   }
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 13

解决此问题的标准方法是使用工厂功能:

var end=8;
for (var i = 1; i < end; i ++) {
       setTimeout(makeResponder(i), 800);
   }

function makeResponder(index) {
    return function () {
        console.log(index);   
   };
}
Run Code Online (Sandbox Code Playgroud)

实例 | 资源

在那里,我们调用 makeResponder循环,并返回一个函数,该函数关闭传递给它的参数(index)而不是i变量.(这很重要.如果您刚从i匿名函数中删除了参数,您的代码将部分工作,但所有函数都会看到i它们运行时的值,而不是最初计划时的值;在您的示例中,它们是所有人都看到了8.)


更新您的评论如下:

......如果我以这种方式称呼它会是正确的setTimeout(makeResponder(i),i*800);吗?

是的,如果您的目标是让每个呼叫比最后一个呼叫晚大约800毫秒,那么这将起作用:

实例 | 资源

我试过setTimeout(makeResponder(i),setInterval(i));function setInterval(index) { console.log(index*800); return index*800; }但是它不能正常工作

你没有使用setInterval那种方式,可能根本不想使用它.


进一步更新:您在下面说过:

我需要先迭代打印8延迟8秒,第二次迭代打印7延迟7秒........打印2延迟2秒...打印0延迟0秒.

您只需再次应用上述原则,使用第二个超时:

var end=8;
for (var i = 1; i < end; i ++) {
       setTimeout(makeResponder(i), i * 800);
   }

function makeResponder(index) {
    return function () {
        var thisStart = new Date();
        console.log("index = " + index + ", first function triggered");
        setTimeout(function() {
            console.log("index = " +
                        index +
                        ", second function triggered after a further " +
                        (new Date() - thisStart) +
                        "ms delay");
        }, index * 1000);
   };
}
Run Code Online (Sandbox Code Playgroud)

实例 | 资源

我想你现在拥有了实现这一目标所需的所有工具.


Iso*_*Iso -2

setTimeout接受变量作为附加参数:

setTimeout(function(a, b, c) {
    console.log(a, b, c);
  }, 1000, 'a', 'b', 'c');
Run Code Online (Sandbox Code Playgroud)

来源

编辑:在您的示例中, 的有效值i可能是8,因为该函数仅在循环完成后被调用。i您需要为每个调用传递当前值:

var end=8;
for (var i = 1; i < end; i ++) {
  setTimeout(function (i) {
      console.log(i);   
   }, 800, i);
}
Run Code Online (Sandbox Code Playgroud)