美文网首页
闭包的理解。

闭包的理解。

作者: 练习时长2年半的个人练习生 | 来源:发表于2020-06-29 17:18 被阅读0次

    js的垃圾回收机制

    当一个函数执行完,js引擎会回收不再使用的内存,闭包通过这个作用域的引用,阻止了垃圾回收。

    什么是闭包

    • 函数在自己声明所在的作用域以外的地方执行才能叫闭包。
    • 保持对外层作用域的引用的行为就是闭包

    闭包的作用 :

    可以在外层访问到函数作用域内部的变量. 减少全局变量,模块化.

    缺点:

    一直保持引用作用域,占用内存

    具体应用:

    利用闭包实现的模块化开发,了解闭包最大的用处其实还是为了更好的书写代码,跟业务关系不大。

           for(var i = 0; i < 6;i++){
               setTimeout(function(){
                   console.log(i)
               }, i*1000);
           }
    

    执行结果:每个一秒 输出一个 6

    • 分析
      1. 因为每声明一个函数就会产生一个作用域 经过6次循环,会产生6个回调函数也就是6个作用域

      2. 因为此法作用域的原因,这六个作用域本身没有i,只能去外层作用域去找,而他们6个外层作用域是同一个作用域, 所以每次函数调用时找到的都是一个i

      3. 当回调函数调用时 外层作用域的变量 i已经变成了6。

    解决办法:

       for (var i = 0; i < 6; i++) { //1
            (function (j) {
                setTimeout(function () {
                    console.log(j)
                }, i * 1000);
            })(i)
        }
    
       for (var i = 0; i < 6; i++) {//2
            (function () {
                 var j = i
                setTimeout(function () {
                    console.log(j)
                }, i * 1000);
            })()
        }
    
    • 思路
    1. 在每个回调函数外层声明一个LIFE,因为每声明一个函数,就会产生一个作用域,当立即执行时,将i 的值保存的单个LIFE的作用域中。
    2. LIFE函数依次执行, 使每个回调函数外层都有一个作用域。
    3. LIFE函数执行时,每次传入的参数都不一样。因此每个回调函数外层作用域里都有一个不一样的i
    4. 当回调函数开始执行时,因为词法作用域的原因,他会去在外边作用域去找i
           for(var i = 0; i <6;i++){   //1
                let j = i;
                setTimeout(() => {
                    console.log(j)
                }, i*1000);
            }
    
           for(let i = 0; i <6;i++){ //2
                setTimeout(() => {
                    console.log(i)
                }, i*1000);
            }
    

    思路基本同上:都是外层包一个作用域
    1. 使用 let 在花括号里创建一个劫持一个块级作用域
    2. 循环六次也就是创建了6个块级作用域
    3. 回调函数执行时都能在自己的外层作用域找到不一样的i

    相关文章

      网友评论

          本文标题:闭包的理解。

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