首页 > javascript for循环后i值变化的问题?

javascript for循环后i值变化的问题?

设置了id为0,1,2,3的四个div,鼠标移入弹出它们的id值,以下代码可以顺利得出每次循环的i值

document.body.onclick=function(){
        for(var i=0;i<4;i++){
        !function(i){
            var o = document.getElementById(i);
            o.onmouseover=function(){
                alert(i);
            }
            alert(i);
        }(i);
        
    }
}

但是修改成这样后i的值一直为4 , 听一些人说是初始化阶段的问题 ,我是一个初学者 , 原理机制能请大牛剖析一下吗?谢谢!

document.body.onclick=function(){
            for(var i=0;i<4;i++){
            
                var o = document.getElementById(i);
                o.onmouseover=function(){
                    alert(i);
                }
                alert(i);
            
            
        }
    }
    

年轻人 用let 吧。小伙子~

for(let i =1;i++;){ ** }


两段代码都涉及闭包,但是:

所以,第一段中4个事件监听器中的i必然是相同 的;第二段中4个事件监听器中i来自4个不同的闭包,而它们的值并不相同。


因为在javascript中for(){}不是一个作用域,所以for循环里面定义的函数读取的i是onclick绑定的匿名函数的活动对象里的i,这个匿名函数活动对象的i当然是在for循环结束后i的值,所以一直是4不会变,具体参考这篇文章
javascript的闭包


讲什么鬼闭包的都是扯淡,这里其实就是一个简单的内存指向问题,新手写代码的时候很容易忽视这么一个问题。

i的指向没有改变 i指向的内容一直有变化,alert中的i 是i指向内容。 循环执行完后i指向的内容为4,alert肯定是4咯。


下面的代码的最内层定义的 function 中调用的 i 其实是循环里面定义的 i. 这个 i 在循环跑完后就等于 4. 当你 mouseover 的时候执行内侧定义的函数时每次都是执行的 alert(4)

而上面的代码中 !function 定义的是一个 immediate-function 定义完成后立即执行,执行时将当时 i 的值带入到函数中形成一个闭包(此时,内侧的 i 和循环中定义的 i 已经没有关系了)。然后最内侧的函数执行时调用的这个 i 的值就是 !function 执行时的那个了。


楼上的兄弟说的都非常好,我再补充一下。

  1. 题主还是要理解闭包,理解闭包之前要先理解javascript的作用域。

  2. function中的i是在执行这个方法的时候再根据作用域开始寻找i的值。

  3. 所以这也就是为什么第二段代码为什么全是4了,因为当方法执行的时候i都变成4了。
    解决的通用办法就是你说的第一段代码,用闭包锁住i的值。


看汤姆大叔的,第三篇有关于你的问题详细解答


自行百度闭包,《javascript高级程序设计》上有相关介绍


建议你去看看闭包吧。
先说第二种方式,通过循环给每个元素绑定mouseover 事件,循环结束,i 值为4. onmouseover 指向一个匿名函数,当事件发生,显示弹框,i 是最后的i,而不是绑定时的值。原因是在函数内定义函数,会形成闭包,内部函数可以访问包含函数内的变量(这里是i),但是内部函数访问的外部函数执行结束后的i值,而不是绑定那一刻的值,因为那一刻,事件还未发生。
对于第一种方式 mouseover 处在一个内部的匿名函数中,并且这个匿名函数直接被调用,由于函数已经执行完毕,所以i值就是那一刻的值,其内部的mouseover事件处理程序访问到也就是这个值。

总结一句就是 闭包使得内部函数可以访问外部函数的变量,具体变量的值是什么取决于内部函数执行的时刻。

【热门文章】
【热门文章】