静坐如禅 2021-08-27 22:27 采纳率: 100%
浏览 67
已结题

关于for循环中变量的引用问题


<body>
    <form id="userForm">
        <div id="advTest">
            <span>0</span>&nbsp;--&nbsp;<span>1</span>&nbsp;--&nbsp;<span>2</span>&nbsp;--&nbsp;<span>3</span>
        </div>
        <hr />
        <div id="advTest2">
            <span>0</span>&nbsp;--&nbsp;<span>1</span>&nbsp;--&nbsp;<span>2</span>&nbsp;--&nbsp;<span>3</span>
        </div>
        <input type="button" value="Test"  id="btnTest" />
    </form>
    <script type="text/javascript">
        //for逻辑块
        var i = 0;
        var spans = $("#advTest span");
        for (i; i < spans.length; i++) {
            spans[i].onclick = function () {
                alert(i);
            }
        }
        i++;

       //if逻辑块
        var v = 0;
        if (true) {
            document.getElementById("btnTest").onclick = function test() {
                alert(v);
            }
        }
        v++;

    </script>
</body>

有些问题不解,希望解答 谢谢:
对于for逻辑体,先抛开i++不说,这个例子是典型for循环内引用全局变量造成绑定都是一个值的问题。在绑定click监听时,函数并未执行,当在触发click时,全局变量i的值是多少就alert多少。如果抛开i++,是4没问题。但是我后面有了i++,在click之前 i 的值已经改变,为什么alert的不是5呢?很是费解。而if逻辑块,输出的就是v++后的值。它们区别在哪呢??

  • 写回答

2条回答 默认 最新

  • 关注

    因为你需要在事件内使用事件外的循环变量i。
    当事件触发时,那个循环早就结束了,那时的i的值已经是循环最大值加1了。
    所以需要用一些方式保存住当前循环的i的值。

    方案一:用闭包保存住当前循环的i的值

    for (var i = 0; i < arr.length; i++) {
        (function(i){
            arr[i].onclick = function () {
                alert(i);
            }
        })(i);
    }
    

    方案二:用let块作用域变量

    for (var i = 0; i < arr.length; i++) {
        let k = i;
        arr[i].onclick = function () {
            alert(k);
        }
    }
    

    ps:IE11中在for语的()内声明的let是整个循环体中共用的,只有在{}内声明的let才是每次循环都独立的。
    非ie的浏览器中可以在中在for语的()内声明let

    for (let i = 0; i < arr.length; i++)
    

    方案三:为事件元素设置一个index属性,在事件函数内通过this获取当前对象并访问index属性。

    for (var i = 0; i < arr.length; i++) {
        arr[i].index = i;
        arr[i].onclick = function () {
            alert(this.index);
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 8月27日
  • 已采纳回答 8月27日
  • 创建了问题 8月27日

悬赏问题

  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试
  • ¥20 问题请教!vue项目关于Nginx配置nonce安全策略的问题
  • ¥15 教务系统账号被盗号如何追溯设备
  • ¥20 delta降尺度方法,未来数据怎么降尺度
  • ¥15 c# 使用NPOI快速将datatable数据导入excel中指定sheet,要求快速高效
  • ¥15 再不同版本的系统上,TCP传输速度不一致
  • ¥15 高德地图2.0 版本点聚合中Marker的位置无法实时更新,如何解决呢?
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题