美文网首页
再谈闭包

再谈闭包

作者: DCbryant | 来源:发表于2017-09-26 21:58 被阅读15次
        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
    

    相关文章

      网友评论

          本文标题:再谈闭包

          本文链接:https://www.haomeiwen.com/subject/mjieextx.html