CodingMonkey_plus 2018-07-29 13:43 采纳率: 0%
浏览 1228
已采纳

JavaScript代码闭包的问题,错误提示:mutable variable is .....

想写个循环测试一下onmouseout,onmouseover,下面是具体代码。

下面这段代码不能正常执行

var yy = document.getElementsByClassName("div_inTop_001");
for (var i = 0; i < yy.length; i++) {
yy[i].addEventListener("mouseover", myfunction0000);
yy[i].addEventListener("mouseout", myfunction0001);
function myfunction0000(){
    yy[i].style.backgroundColor="#A52A2A";
    console.log(i);
}
function myfunction0001(){
    yy[i].style.backgroundColor="#5B5B5B";
    console.log(i);
}
}

错误提示:开发工具(idea)提示:mutable variable is accessible from closure
浏览器报错提示:
图片说明

可以正确执行的代码:

var yy = document.getElementsByClassName("div_inTop_001");
for (var i = 0; i < yy.length; i++) {
yy[i].addEventListener("mouseover", myfunction0000);
yy[i].addEventListener("mouseout", myfunction0001);
function myfunction0000(){
    this.style.backgroundColor="#A52A2A";
    console.log(i);
}
function myfunction0001(){
    this.style.backgroundColor="#5B5B5B";
    console.log(i);
}
}

我想知道为什么上面的那一段代码不能运行?下面那段代码为什么能运行
yy.length=5

  • 写回答

2条回答 默认 最新

  • 天际的海浪 2018-07-29 16:49
    关注
    因为你需要在事件内使用事件外的循环变量i。
    你的循环中只是为元素绑定事件,这时事件并没有触发执行。
    等到事件触发时,那个循环早已经结束了,那时的i的值已经是循环最大值加1了。
    所以需要用一些方式保存住当前循环的i的值。
    方案1为:用闭包保存住当前循环的i的值。
    for(var i=0;i<doms.length;i++) {
        (function(i){
            doms[i].onclick=function(){
                alert(i);
            }
        })(i);
    }
    
    方案2为:用let块作用域变量,原理也是闭包(ie11以前不支持)
    for(var i=0;i<doms.length;i++) {
        let j = i;
        doms[i].onclick=function(){
            alert(j);
        }
    }
    
    方案3为:在事件函数内不使用循环变量i,而是用this获取触发事件的元素
    for(var i=0;i<doms.length;i++) {
        doms[i].index = i;
        doms[i].onclick=function(){
            alert(this.index);
        }
    }
    
    如果你只是要获取触发事件的元素,而不需要使用循环变量i。可以直接在事件函数内用this就可以了。
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥30 NIRfast软件使用指导
  • ¥20 matlab仿真问题,求功率谱密度
  • ¥15 求micropython modbus-RTU 从机的代码或库?
  • ¥15 铜与钢双金属板叠加在一起每种材料300mm长,18mm宽,4mm厚一端固定并加热至80℃,当加热端温度保持不变时另一端的稳态温度。ansys
  • ¥15 django5安装失败
  • ¥15 Java与Hbase相关问题
  • ¥15 后缀 crn 游戏文件提取资源
  • ¥15 ANSYS分析简单钎焊问题
  • ¥20 bash代码推送不上去 git fetch origin master #失败了
  • ¥15 LOL外服加入了反作弊系统,现在游戏录像rofl文件离线都无法打开