美文网首页
再谈闭包

再谈闭包

作者: 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

相关文章

  • 再谈闭包

    这里居然打出5,为什么不是10呢?为什么不是3呢?有很多人知道i引用的是全局变量i,可以用闭包解决这个问题,那么为...

  • 再谈JS闭包

    js中的闭包其实是对于局部作用域的保持,如果没有这个特性,便无法取到函数内局部作用域内的私有变量。函数内部以子函数...

  • JavaScript闭包再谈

    虽然前面写过一篇文章说闭包JavaScript模块化和闭包,但是一位美女程序员朋友讨论的时候好像并不能理解那边文章...

  • JS闭包大结局(JS闭包系列3)

    在上一篇中再谈JS闭包(JS闭包系列2),我详细的介绍了JS中的变量作用域相关的概念,结合第一节关于JS闭包(JS...

  • 再谈JS闭包(JS闭包系列2)

    这篇文章,来继续谈谈Javascript闭包的剩余问题。因为在上一篇文章中关于JS闭包(JS闭包系列1)主要简单的...

  • swift-闭包

    闭包 闭包定义 闭包简化 - 尾随闭包 闭包参数 闭包返回值 闭包的循环引用

  • 闭包,闭包,闭包

    1、这家伙到底是什么? 网上关于这个的讨论的太多了太多了,有各种的举例子,但是大部分还在寻找这个答案的小伙伴对于变...

  • 闭包-Closures [swift 5.1]

    闭包的语法 尾随闭包 闭包逃离 自动闭包

  • Day7 闭包(Closures)

    本页包含内容:• 闭包表达式• 尾随闭包• 值捕获• 闭包是引用类型• 逃逸闭包• 自动闭包 1、闭包表达式 闭包...

  • Python闭包

    闭包 = 环境变量 + 函数 调用闭包内部的环境变量 闭包的经典误区 闭包与非闭包实现人类走路 非闭包 闭包

网友评论

      本文标题:再谈闭包

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