再谈闭包

    var fnArr = [];
    for (var i = 0; i < 10; i ++) {
        fnArr[i] =  function(){
            return i;
        };
    }
    i = 5
    console.log( fnArr[3]() );  //5

这里居然打出5,为什么不是10呢?为什么不是3呢?有很多人知道i引用的是全局变量i,可以用闭包解决这个问题,那么为什么会这样呢?还牵扯到了函数的执行原理,因为函数又是一个对象,对象会被存到堆内存中,所以函数当函数没有执行的时候,就把函数当做字符串放在堆内存中,数组中存储的,其实只是指向这个堆内存的指针,i并没有传进去,执行的时候i才被传进去

 fnArr[0] =  function(){
     return i
 }
 fnArr[1] =  function(){
     return i
 }

直到函数执行的时候浏览器才会解析这段字符串,把他当做函数来执行,所以当我们执行函数的时候,i已经循环到10了,i取到的就是全局变量10,之后我们把i赋值为5,i取到的就是5了。

这时候我们就发现一个问题,我们想取到每一个i值,怎么办呢?可以把它放到局部作用域,这时候就轮到闭包大展身手了,闭包的作用就是创建一个局部作用域,保存变量

所以有了之后的一系列的闭包写法

所以这个题的重点不在于闭包,而在于你对于函数执行了解的程度,如果你能完全理解为什么i变成10,而不是只知道i为10,那么之后写成闭包就是在自然不过的事了,因为你知道这段代码有什么问题,那么就只剩解决问题了,可是,程序员的天职不就是解决问题吗?

最后附一下解决办法:

方法1:

        //自执行函数
        var fnArr = [];
        for (var i = 0; i < 10; i ++) {
            fnArr[i] =  function(i){
                return function(){
                    return i;
                }
            }(i)
        }
        console.log( fnArr[3]() );  //3

方法2:

        //自执行函数
        var fnArr = [];
        for (var i = 0; i < 10; i ++) {
            fnArr[i] =  (function(){
                var temp = i
                return function(){
                    return temp
                }
            })()
        }
        console.log( fnArr[3]() );  //3

方法3:

        var fnArr = [];
        for (var i = 0; i < 10; i ++) {
            !function(i){
                fnArr[i] =  function(){
                    return i;
                }
            }(i)
            
        }
        console.log( fnArr[3]() );  //3

方法4:

        var fnArr = [];
        for (let i = 0; i < 10; i ++) {
            fnArr[i] =  function(){
                return i;
            };
        }
        console.log( fnArr[3]() );  //3
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,510评论 11 349
  • 昨晚十点零5分,刚听完梁小同学《北冥是一种很悬的东西》《不确定的世界 无限可能》准备进入深睡眠时,吴小同学打来电话...
    林a林阅读 1,490评论 0 0
  • 最近在折腾MongoDB,在用PHP连接过程中发现诸多问题,最后选择用了PHPLIB,也写下来心酸历程,以便查阅。...
    我是大彬子阅读 3,870评论 0 0
  • 很小的時候,不為了自己,很少哭。看影視劇:親近的人去世了,主角哭得死去活來。我當時暗暗地想,如果我身在其中,哭不出...
    宵夜想换个英文名阅读 2,383评论 0 2

友情链接更多精彩内容