javascript - 循环遍历为什么需要将 i 再记录一遍?
大家讲道理
大家讲道理 2017-04-11 13:28:18
[JavaScript讨论组]

js代码如下:

window.onload = function() {
        var menu = document.getElementById('menu'),
            ps = menu.getElementsByTagName('p'),
            uls = menu.getElementsByTagName('ul');
        for (var i = 0; i < ps.length; i++) {
            ps[i].id = i;  //为什么这里需要将 i 再记录一遍?
            ps[i].onclick = function() {
                uls[this.id].style.display = "block"; //这里直接写usl[i].style.display="block" 为什么不行?它们不是同一个i吗?
            };
        }
    };

html代码如下:

Web前端

  • JavaScript
  • p+CSS
  • jQuery

后台脚本

  • PHP
  • ASP.net
  • JSP

前端框架

  • Extjs
  • Esspress
  • YUI

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回复(5)
巴扎黑

因为onClick不是立即执行的,实际上当事件处理函数执行时,这里如果使用i的话会引用同一个i,而且这个i值等于for循环结束时i的值。

实际上这里起的效果跟闭包是一样的,具体效果是让每一个事件处理函数都有属于它自身的i值,而不是引用同一个i。

高洛峰

如果你想直接使用usl[i],需要使用let方式声明i。使用var声明不行的原因上面的回答已经说了,let声明的变量是在块内有效的。

怪我咯
<p class="menu" id="menu">
    <p>
        <p>Web前端</p>
        <ul style="display:none;">
            <li>JavaScript</li>
            <li>p+CSS</li>
            <li>jQuery</li>
        </ul>
    </p>
    <p>
        <p>后台脚本</p>
        <ul style="display:none;">
            <li>PHP</li>
            <li>ASP.net</li>
            <li>JSP</li>
        </ul>
    </p>
    <p>
        <p>前端框架</p>
        <ul style="display:none;">
            <li>Extjs</li>
            <li>Esspress</li>
            <li>YUI</li>
        </ul>
    </p>
 </p>
<script>
window.onload = function() {
    var menu = document.getElementById('menu');
    var ps = menu.getElementsByTagName('p');
    var uls = menu.getElementsByTagName('ul');
    for (var i = 0; i < ps.length; i++) {
        (function(i){
            ps[i].onclick = function() {
                uls[i].style.display = "block";
            };
        })(i);
    }
};
</script>
阿神

因为闭包的存在

迷茫

你代码用的是var,函数作用域,for里面所有对i的引用都是共用同一块作用域。
因为js不是惰性求值,所以你代码里再记录一次i的时候,直接取得了当前i的值,而不是运行时查询闭包,所以能实现获取不同i值。如果不想再记录一遍的话,要不用let块作用域;要不每回访问i都建一个闭包存起来,但是这样子的话跟再记录一遍其实原理并没有大的差别,在代码量简单变量少的情况下随意建闭包就有点太浪费性能了。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号