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

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

  •  
  •   manyfreebug · 2019-05-21 21:25:21 +08:00 · 2969 次点击
    这是一个创建于 1773 天前的主题,其中的信息可能已经有所发展或是发生改变。
    下面的代码中,为什么 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
    rabbbit
        1
    rabbbit  
       2019-05-21 21:29:35 +08:00
    for(var i = 0; i < elems.length; i++ ){
    ->
    for(let i = 0; i < elems.length; i++ ){

    知识点: 作用域 闭包
    ted94
        2
    ted94  
       2019-05-21 21:37:49 +08:00 via Android
    闭包。你都有输出 i 了。
    molvqingtai
        3
    molvqingtai  
       2019-05-21 22:00:30 +08:00
    把 var 改为 let
    wi
        4
    wi  
       2019-05-21 22:09:56 +08:00
    闭包,for 执行完之后 i == elems.length
    iugo
        5
    iugo  
       2019-05-21 22:41:33 +08:00   ❤️ 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);
    }
    ```
    brust
        6
    brust  
       2019-05-22 09:09:00 +08:00
    把 var i 换成 let i
    chenyu0532
        7
    chenyu0532  
       2019-05-22 09:42:31 +08:00
    自从看了 var let 的区别,反正我是完全抛弃了 var
    manyfreebug
        8
    manyfreebug  
    OP
       2019-05-22 18:08:21 +08:00
    都提到了闭包,看来是我没掌握闭包
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1218 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 18:06 · PVG 02:06 · LAX 11:06 · JFK 14:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.