首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
V2EX  ›  JavaScript

下面的代码中,为什么 elems[i]的结果是 undefined?

  •  
  •   manyfreebug · 36 天前 · 945 次点击
    这是一个创建于 36 天前的主题,其中的信息可能已经有所发展或是发生改变。
    下面的代码中,为什么 elems[i]的结果是 undefined?
    
    代码及运行效果也可在 JS Bin 中查看:https://jsbin.com/tixujoyibu/edit?html,css,js,console,output
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>JS Bin</title>
    </head>
    <body>
      <div class="link">
        <a href="#">壹</a>
        <a href="#">贰</a>
        <a href="#">叁</a>
        <a href="#">肆</a>
      </div>
    </body>
    </html>
    
    var elems = document.getElementsByTagName("a");
    
    for(var i = 0; i < elems.length; i++ ){
        elems[i].addEventListener("click",function(){
          console.log("i = " + i);
        //运行结果:"I am link # undefined",为什么得到的 elems[i]是 undefined 呢?   
          console.log("I am link # " + elems[i]); 
      });
        
    }
    
    8 回复  |  直到 2019-05-22 18:08:21 +08:00
        1
    rabbbit   36 天前
    for(var i = 0; i < elems.length; i++ ){
    ->
    for(let i = 0; i < elems.length; i++ ){

    知识点: 作用域 闭包
        2
    ted94   36 天前 via Android
    闭包。你都有输出 i 了。
        3
    molvqingtai   36 天前
    把 var 改为 let
        4
    wi   36 天前
    闭包,for 执行完之后 i == elems.length
        5
    iugo   36 天前   ♥ 1
    作为初中教师资格证持有者, 详解一下:

    ```
    for(var i = 0; i < 4; i++){
    elems[i].addEventListener("click",function(){
    console.log("i = " + i);
    });
    }
    ```

    1. 当 for 循环执行时, 在外层作用域定义了一个 i, 初始值是 0.
    2. 事件监听函数会从外部引入一个变量 i. (所谓闭包)
    3. 每次 i < 4 判断成功之后, 都执行一次 i++, 所以 i = 3 时, 后面跟着执行了 i++, 此时 i = 4. 下次再判断时不再成立, 所以 i 停留在 4.
    4. 数组长度为 4, 只有 0,1,2,3. 所以 elems[4] 就是 undefined.

    或许换成以下这样你能理解:

    ```
    var i = 0;
    for(; i < 4; i++){
    elems[i].addEventListener("click", test);
    }
    function test(){
    console.log("i = " + i);
    }
    ```
        6
    brust   35 天前
    把 var i 换成 let i
        7
    chenyu0532   35 天前
    自从看了 var let 的区别,反正我是完全抛弃了 var
        8
    manyfreebug   35 天前
    都提到了闭包,看来是我没掌握闭包
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   896 人在线   最高记录 5043   ·   Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 21ms · UTC 21:58 · PVG 05:58 · LAX 14:58 · JFK 17:58
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1