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

[Javascript] 请问这两段代码有什么不一样吗?

  •  1
     
  •   click · 2014-10-12 11:19:58 +08:00 · 3983 次点击
    这是一个创建于 3482 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本人正在学JS,做一个标签切换效果,有个问题很久没搞不懂。

    mDD.length=2 请问这两段代码又什么不一样吗,测试效果不一样。

    代码1:

    for (var i=0;i<mDD.length;i++){
            mDD[i].addEventListener('mouseover',function(){onMou(i)});
    }
    

    代码2:

    mDD[0].addEventListener('mouseover',function(){onMou(0)});
    mDD[1].addEventListener('mouseover',function(){onMou(1)});
    

    代码1实现不了效果,换成代码2成功。

    22 条回复    2014-11-09 18:50:48 +08:00
    willwen
        1
    willwen  
       2014-10-12 11:30:05 +08:00 via iPhone   ❤️ 1
    經典的閉包問題⋯Google "JavaScript 閉包 事件綁定",有你要的答案
    simonhtq
        2
    simonhtq  
       2014-10-12 11:31:23 +08:00
    1L正解
    ChJJin
        3
    ChJJin  
       2014-10-12 11:32:13 +08:00
    循环后,i为2,楼上说对了,闭包问题
    bombless
        4
    bombless  
       2014-10-12 12:01:09 +08:00
    经典问题…在闭包中你绑定的是变量而不是值。
    你需要在闭包外面再包一个闭包,然后把不变的量通过参数传过去。
    像这样:
    (function(j){ return function(){ onMou(j); }; })(i)
    newghost
        5
    newghost  
       2014-10-12 12:04:18 +08:00
    1的结果其实是这样的:

    mDD[0].addEventListener('mouseover',function(){onMou(1)});

    mDD[1].addEventListener('mouseover',function(){onMou(1)});
    newghost
        6
    newghost  
       2014-10-12 12:05:13 +08:00
    @newghost

    onMou(2)
    onMou(2)
    zhujinliang
        7
    zhujinliang  
       2014-10-12 12:19:00 +08:00 via Android
    对数组遍历建议使用forEach
    Automan
        8
    Automan  
       2014-10-12 12:24:35 +08:00
    @zhujinliang js里明显应该用for i
    sneezry
        9
    sneezry  
       2014-10-12 12:33:48 +08:00
    第一段代码里,i的作用域弄混了,for循环结束后i的值是个定值,无论哪个dom触发mouseover事件,后面函数里的i都是定值。
    Doubear
        10
    Doubear  
       2014-10-12 12:59:45 +08:00
    @bombless 闭包 这个名称是怎么来的?
    aa65535
        11
    aa65535  
       2014-10-12 13:10:48 +08:00
    chone
        12
    chone  
       2014-10-12 13:54:56 +08:00 via iPhone   ❤️ 1
    for不产生作用域,所以绑定的两个函数中的i在中一个作用域中,因此最终的值是一样的。
    zyue
        13
    zyue  
       2014-10-12 14:14:17 +08:00
    先unbound 下 再bound
    jianghu52
        14
    jianghu52  
       2014-10-12 14:16:39 +08:00
    所以一般来说,代码1里面通常会这么写
    var j = i
    mDD[j].addEventListener('mouseover',function(){onMou(j)});
    click
        15
    click  
    OP
       2014-10-12 15:09:38 +08:00
    v2ex帖子怎么实现代码着色的,我刚发的时候没有颜色的啊。
    Mutoo
        16
    Mutoo  
       2014-10-12 16:12:07 +08:00   ❤️ 1
    @jianghu52 这样写一样的,`j`和`i`在同一层闭包里。
    Jaylee
        17
    Jaylee  
       2014-10-12 16:16:02 +08:00
    ```
    for (var i=0;i<mDD.length;i++){
    (function(i){
    mDD[i].addEventListener('mouseover',function(){onMou(i)});
    })(i)

    }

    ```
    ChanneW
        18
    ChanneW  
       2014-10-12 17:52:17 +08:00
    经典
    Mutoo
        19
    Mutoo  
       2014-10-12 22:38:13 +08:00
    @click /t/127980 新建topic后,点击编辑,右下角多了个选项,文本标记语法,改为Markdown即可.
    bombless
        20
    bombless  
       2014-10-13 16:05:19 +08:00   ❤️ 1
    @Doubear closure,用来表达一种两个集合的包含关系
    cdxem713
        21
    cdxem713  
       2014-10-20 13:24:52 +08:00
    @Jaylee 昨天被面试官考了这个问题,他给的标准答案就这个
    click
        22
    click  
    OP
       2014-11-09 18:50:48 +08:00
    @Jaylee 谢谢!成功了,但还是无法理解

    (function(i){
    mDD[i].onmouseover=function(){onMou(i)};
    })(i);
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   998 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 20:11 · PVG 04:11 · LAX 13:11 · JFK 16:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.