日期:2014-05-16  浏览次数:20350 次

为什么这个不是闭包
JScript code

function a()
{
    var array = new Array();
    for (var i = 0; i < 10; i++)
    {
        array.push(function() {return i});
    }
    
    return array;
}

var array = a();
for (var i = 0; i < array.length; i++)
{
    window.alert(array[i]()); //全是10
}


请问为什么这个不是闭包?我是认为,内部函数引用外部函数的变量,并且内部函数返回给了一个全局变量,符合闭包的条件。但在这个帖中http://topic.csdn.net/u/20111202/10/1a48255e-14ca-4ccc-b814-f36af80696e2.html?84111都认为这个不是闭包。

------解决方案--------------------
内部函数引用外部函数的变量,外部函数的变量i只有一个值
------解决方案--------------------
JScript code

function a()
{
    var array = new Array();
    for (var i = 0; i < 10; i++)
    {
        array.push(function() {return i}); //这个i并不是内部函数的局部变量,怎么会是闭包呢,function(i) {return i;} 这个内部函数的局部变量i才是闭包
    }
    
    return array;
}

------解决方案--------------------
纯粹的闭包
只是不是你想象中的闭包
------解决方案--------------------
function() {return i} 这样的语句并没有被执行,只是构建了一个函数体为return i;的函数对象,仅此而已。当i=10时,迭代停止,外部函数返回。当再去调用array[i]()时,i的值依旧为10。因此每一个元素的array都返回i=10。 跟我之前看到的一个例子一样,很相似……

------解决方案--------------------
都是闭包。
函数执行创建作用域,函数声明绑定作用域。
JScript code

<script>
function f(x) 
{  
    var g = function () { return x; }  
    return g;  
}
</script>

------解决方案--------------------
所以你每次执行f,都会重新声明一次g,然后g里面的x因为本身未定义,就会到f域去找。
------解决方案--------------------
而你主贴贴的代码,不是闭包还能是啥呢?
------解决方案--------------------
闭包是一个动态的概念,是在函数运行时存在的,如果当前函数内没有此变量,则从父函数中去直至到顶。所以欲行时取i,此时i为10