zoukankan      html  css  js  c++  java
  • JS

    可能大多数人平时大量写js代码,但是对闭包还是模模糊糊。本文记录自己学习闭包的一些知识点。

    function foo() {
        var a = 2;
        function bar() {
            console.log(a)
        };
        return bar;
    }
    
    var result = foo()  // result就是foo返回的bar
    result() // 调用了bar,成功访问了函数作用域中的变量a

    以上就是一个闭包的代码。foo()执行后,foo()内部作用域会被销毁,JS垃圾回收器回收无用的空间,释放内存。但是由于闭包的存在,会使它一直存在。因为bar()本身在使用这个作用域。bar()对foo()作用域的引用就叫闭包。

    传递函数的方式观察闭包,通过内部函数baz传递过来,由于baz涵盖了foo作用域,所以能够访问到a

    function foo() {
        var a;
        function bar() {
            console.log(a)
        }
        baz(bar)
    }
    
    function baz(fn) {
      fn()   //这就是闭包
    }

    在平时编码过程中,闭包随处可见。比如将函数作为参数到处传,那么就会在这些函数调用中找到闭包。比如平时常见的定时器。

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

    以上代码,我们期望它能每一秒依次输出1-5,但是其实它的结果是 6 个 6,这是由于 i 其实是一个全局作用域,并没有在每次循环中存储。for循环到最后i的结果是6。

    我们可以通过闭包来解决这种问题,将每次循环的i值传入闭包函数中进行存储。

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

    es6中新增了let,也可以解决以上问题,更加简便。

    for(let i=0; i<=5; i++) {
        setTimeout(function timer() {
            console.log(i)
        }, i*1000)
    }
  • 相关阅读:
    [tarjan][树上差分] Codeforces 555E Case of Computer Network
    [线段树] Jzoj P1214 项链工厂
    [矩阵乘法] Jzoj P2288 沼泽鳄鱼
    [状压dp][dfs] Jzoj P2679 跨时代
    [spfa][差分约束] Bzoj 2330 糖果
    [spfa] Bzoj 2118 墨墨的等式
    [倍增][Floyd] Bzoj 2165 大楼
    [虚树][树形dp] Bzoj P3611 大工程
    [虚树][树形dp] Bzoj P2286 消耗战
    [数位dp] Jzoj P3316 非回文数字
  • 原文地址:https://www.cnblogs.com/zhoujin-Jojo/p/13848742.html
Copyright © 2011-2022 走看看