setTimeout和匿名函数问题 [英] setTimeout and anonymous function problem

查看:599
本文介绍了setTimeout和匿名函数问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码,使用错误的值调用SetOpacity,为什么?

This is my code, SetOpacity get invoked with wrong values, why?

function SetOpacity(eID, opacity){                  
   eID.style.opacity = opacity / 100;
   eID.style.filter = 'alpha(opacity=' + opacity + ')';
}
function fade(eID, startOpacity, endOpacity){           
    var timer = 0;
    if (startOpacity < endOpacity) { 
       for (var i = startOpacity; i <= endOpacity; i++) {
           setTimeout(function() {SetOpacity(eID, i);}, timer * 30);
           timer++;
        }
    }           
}


推荐答案

这应该有效:

for (var i = startOpacity; i <= endOpacity; i++) {
    (function(opacity) {
        setTimeout(function() {SetOpacity(eID, opacity);}, timer * 30);
    })(i);
    timer++;
}

此作品如下:


  • 在你创建匿名函数的内部循环中( function(...){...} )并立即用参数调用它(这就是为什么 function(){} 附近有括号的原因,所以你可以在结束时调用它添加()并传递参数)

  • 传递给此匿名函数的参数( i 值, opacity 内部函数)是这个匿名函数的本地函数,因此它们不会在循环的下一步中更改,并且您可以将它们传递给另一个匿名函数(在 setTimeout

  • inside loop you create anonymous function (function(...){...}) and immediately call it with parameter (that's why there are parenthesis around function(){}, so you can call it adding () at end and pass parameters)
  • parameters passed to this anonymous function (i value, which is opacity inside function) are local to this anonymous function, so they don't change at next steps of loop, and you can safelly pass them to another anonymous function (this at setTimeout)

您的原始版本无效,因为:

Your original version didn't worked because:


  • 你的函数传递给 setTimeout 保存对变量 i 的引用(不是它的值),以及它在调用此函数时获取值,而不是在将其添加到 setTimeout

  • va时这个变量的lue在循环中被改变,在你获得第一个 setTimeout 之前,它获得 endOpacity value(最后一个值来自 for loop)

  • your function passed to setTimeout holds reference to variable i (not value of it), and it gets value when this function is called, which is not at time of adding it to setTimeout
  • the value of this variable gets changed in loop, and before you even get first setTimeout it gets endOpacity value (last value from for loop)

不幸的是JavaScript只有函数范围,所以它赢了'如果你在循环中创建变量并分配新的实际值,则工作,因为只要函数内部有一些 var ,这些变量就会在函数执行时创建(并获取 undefined 默认值)。创建新范围的唯一(简单)方法是创建函数(可能是匿名的)并在其中创建新变量(参数也是变量)

Unfortunately JavaScript only has function scope, so it won't work if you create variable inside the loop and assign new actual value, because whenever there is some var inside function, those variables are created at time of function execution (and get undefined value by default). The only (easy) way to create new scope is to create function (may be anonymous) and create new variables inside them (parameters are variables too)

这篇关于setTimeout和匿名函数问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆