Javascript 闭包失败-即使阅读了所有相关内容

Javascript 闭包失败-即使阅读了所有相关内容,javascript,closures,Javascript,Closures,我有倒计时 我想在onload中进行以下工作,但我显然有闭包的问题 for (var o in myDates) { var myDate = myDates[o]; var iid = o; funcs[o] = function() { var dateFuture = new Date(); dateFuture.setSeconds(dateFuture.getSeconds()+myDate.durationInSecs); GetCount(da

我有倒计时

我想在onload中进行以下工作,但我显然有闭包的问题

for (var o in myDates) {
  var myDate = myDates[o];
  var iid = o;
  funcs[o] = function() {
    var dateFuture = new Date();
    dateFuture.setSeconds(dateFuture.getSeconds()+myDate.durationInSecs);
    GetCount(dateFuture,iid);    
  }
  myDates[iid].tId = setTimeout("funcs['"+iid+"']()",myDates[o].delay*1000);
}
下面的代码可以工作。 但是它有一个隐式eval和两个全局变量,我想像上面的非工作代码一样循环



变量myDates={
d0:{
持续时间:5,
延迟:0,
重复:错,
在消息中:“直到发生什么事”,
尾语:“发生了什么事”,
重复消息:“
}, 
d1:{
持续时间:10,
延误:3,
重复:对,
在消息中:“直到其他事情发生”,
endMessage:“发生了其他事情”,
repeatMessage:“这将在3中重复”
}
}
var funcs={};
window.onload=function(){
//如果我在闭包方面做得更好,下面的内容可以在一个循环中完成
setTimeout(函数(){
funcs[“d0”]=函数(){
var myDate=myDates[“d0”];
var dateFuture0=新日期();
dateFuture0.setSeconds(dateFuture0.getSeconds()+myDate.durationInSecs);
GetCount(dateFuture0,“d0”);
}
funcs[“d0”]();
},myDates[“d0”]。延迟*1000);
// ---------------
setTimeout(函数(){
funcs[“d1”]=函数(){
var myDate=myDates[“d1”];
var dateFuture1=新日期();
dateFuture1.setSeconds(dateFuture1.getSeconds()+myDate.durationInSecs);
GetCount(dateFuture1,“d1”);
}
funcs[“d1”]();
},myDates[“d1”]。延迟*1000);
};
//######################################################################################
//作者:ricocheting.com
//版本:v2.0
//日期:2011-03-31
//描述:显示在下面输入“dateFuture”之前的时间量。
//注意:输入的月份必须比当前月份少一个。ie;0=一月,11=十二月
//注:小时为24小时格式。上午0点=12点,下午15点=3点等
//格式:dateFuture1=新日期(年、月、日、小时、分钟、秒)
//示例:dateFuture1=新日期(2003,03,26,14,15,00)=2003年4月26日-下午2:15:00
//测试:注释下面的行,打印“dateFuture”以进行测试
//文件。写(dateFuture+“
”); //################################### //没有超过这一点的 函数GetCount(ddate,iid){ dateNow=new Date();//获取当前日期 amount=ddate.getTime()-dateNow.getTime();//计算日期之间的毫秒数 delete dateNow;//这在IE中安全吗? var myDate=myDates[iid]; //如果时间已经过去 如果(金额<0){ document.getElementById(iid).innerHTML=myDate.endMessage; 如果(myDate.重复){ setTimeout(funcs[iid],myDate.delay*1000); document.getElementById(iid).innerHTML=myDate.repeatMessage; } } //否则日期还是好的 否则{ secs=0;out=“”; amount=Math.floor(amount/1000);//去掉“毫秒”,只需秒 秒=Math.floor(数量);//秒 out+=secs++((secs==1)?“sec”:“secs”)+“,”; out=out.substr(0,out.length-2); document.getElementById(iid).innerHTML=out+myDate.duringMessage; 文件名称=iid; setTimeout(函数(){GetCount(ddate,iid)},1000); } } !! ??
您落入了在循环中声明闭包的陷阱。内部函数关闭变量myDate,且不超过其值。这尤其出乎意料,因为变量应该具有块作用域,并且不会在多次迭代中保持不变(在Javascript中不是这种情况——一切都是函数作用域)

您可以通过使用闭包生成器函数来解决此问题。通过这种方式,您可以创建一个新的变量实例来随意关闭

错误

var i;
for(i=0; i<xs.length; i++){
    something = function(){
        f(i);
    };
}
//all closures share the i variable and will have it
//be i=xs.length in the end. We don't want that.
vari;

对于(i=0;IDown选民:请评论原因!不是我,而是“帮助我”的问题标题有点不受欢迎;而且你不太清楚什么不起作用/预期的结果是什么。但是你看到了我做了什么…-我重新措辞了问题
var i;
for(i=0; i<xs.length; i++){
    something = function(){
        f(i);
    };
}
//all closures share the i variable and will have it
//be i=xs.length in the end. We don't want that.
function make_handler(i){
    return function(){
        f(i);
    };
    //each call gets its own copy of i
}
var i;
for(i=0; i<xs.length; i++){
    something = make_handler(i);
}
var i;
for(i=0; i<xs.length; i++){
    something = (function(i){
        return function(){
            f(i);
        };
    }(i));
}