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)
    }
  • 相关阅读:
    无限循环小数化分数、
    HDU 1060
    HDU 2601
    HDU 1286
    HDU 1071
    有关SQLite的substr函数的笔记
    Android 在安装完成界面,点击打开应用程序。在应用程序点击home键,再从桌面打开程序导致产生多个实例或者说程序被重复打开
    酷派8150S(移动定制版)可用的第三方Recovery备份数据、刷机并精简系统内置APK经验
    个人经验
    批处理脚本
  • 原文地址:https://www.cnblogs.com/zhoujin-Jojo/p/13848742.html
Copyright © 2011-2022 走看看