一个经典闭包问题

图片描述
为什么结果是是3而不是2呢

阅读 2.4k
3 个回答

把闭包的概念代进去看吧:
函数内部嵌套函数——>
就是for实现的定义在数组上的函数。

在外部引用函数内部的局部变量——>

var arr = F();//获得了包含三个函数的数组
arr[0]();
arr[1]();
arr[2]();
//这三个函数就实现了在函数外部引用函数内部的变量

结果为3的原因——>
因为js唯一的局部作用域就是函数,因而F中的for循环并没有将i作为局部变量传到那三个函数中去,因此那三个函数依然是引用的F中的i,在循环体结束时,i的值递增到了3,因此在整个F环境下i的值都为3了,所以在外部引用到arr中的任何一个函数,都是对这个i的引用,因此所有的值都为3。

var arr = F(); // i最后一次循环执行时是2,然后i++值就是3(这时匿名函数并未执行)
arr[0](); // 执行匿名函数,这是去取i的值,当然是3
arr[1](); // 执行匿名函数,这是去取i的值,当然还是3
arr[2](); // 执行匿名函数,这是去取i的值,当然还还是3

若期望输出0,1,2,可以改成如下形式

function F() {
    var arr=[], i;
    for(i=0;i<3;i++) {
        (function(i) {            // 新增行
            arr[i] = function() {
                return i;
            };
        })(i);                    // 新增行
    }
    return arr;
}

传统来说,一个函数执行完后,其存在堆中的局部变量都会被清除,但是JavaScript里闭包涉及到的其所在的各级祖先函数中的局部变量在各自执行完后不会被从堆中清除,或者说它们可能存在另一个“永久堆”里。

其实楼主可以把是2的理由讲一下。

楼主还是想想最后i的值是多少 就知道答案了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题