JS 闭包


在JS中,当内部的方法被其他对象引用,如果内部的方法使用了外部方法的变量,将造成外部方法无法释放,变量将被保持,此时将形成闭包。

看一个例子

<a href="#" id="closureTest1">闭包测试1</a><br />
<a href="#" id="closureTest2">闭包测试2</a><br />
<a href="#" id="closureTest3">闭包测试3</a><br />
function closureTest(){
    for (var i = 1; i < 4; i++) {
       var element = document.getElementById('closureTest' + i);
       element.onclick = function(){
            alert(i);
        }
    }
}

此时无论点击哪个超链接,弹出的都是3,这是因为onclick触发时,绑定函数才会去初始化i的值,而i引用自外部函数closureTest,在closureTest中,i早已递增到3。

解决办法很简单,不闭包就行了。

function badClosureExample(){
   for (var i = 1; i <4; i++) {
       var element = document.getElementById('closureTest' + i);
       element.onclick =  clickCall(i);
   }
}

function clickCall(j){
    return function(){
        alert('您单击的是第' + j + '个链接');
    }
}

闭包也并非全然有害,有时我们也可以利用做些有趣的事,例如定时任务的传参

function bind(){
    var element = document.getElementById('closureTest0');
    element.onclick = function(){
        setTimeout(function(p){
            return function(){
                alert(p);
            }
        }('998'), 1000); //延迟1秒弹出提示
    }
}