2009年11月16日星期一

[note]常在河边走、哪有不湿鞋。被闭包灭了

如题,今天被一个闭包导致的bug困扰了大概15分钟。代码如下(基于jQuery):

    for (var i=1; i<3; i++) {
        $('label.labelTag:first').clone().text("第"+ (i+1) +"条跑道").click(function() {
                console.log(i);
                Runway.moveToRunway(i);
        }).appendTo(wrapper);
    }

看似天衣无缝,但执行的时候 打印出来的i都是“3”!!!

原因就是闭包作怪,jQuery的click函数是设置DOM元素被点击时的动作,它的参数只有一个函数引用。这里就是

function() {
       console.log(i);
       Runway.moveToRunway(i);
}

这个函数在非闭包语言中肯定不能执行,因为变量i未定义!!!在JS中却可以,因为闭包所以只要i被引用了,它就一直会存在。
说到这里,原因也明白了。i一直在由于i++的原因,一直增长到了3。把代码修改成以下形式就又可以使用了!

    for (var i=1; i<3; i++) {
        $('label.labelTag:first').clone().text("第"+ (i+1) +"条跑道").attr("onClick",
                "Runway.moveToRunway("+ i +");").appendTo(wrapper);
    }

这样就不引用函数了,产生不了闭包!

没有评论: