闭包

作者: 再见噜噜班 | 来源:发表于2019-11-29 20:38 被阅读0次

MDN:函数与对其状态即词法环境(lexical environment)的引用共同构成闭包(closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在JavaScript,函数在每次创建时生成闭包。
用例子说明:

function foo(){//foo的作用域中声明了局部变量a和函数bar,bar是foo的内部函数,只能在foo内部访问
    var a=1
    function bar(){//根据变量在作用域中由内而外的查找过程,bar函数能访问其父函数foo中的局部变量a
        console.log(a)
    }
    bar()
}
foo() 

注意:词法(lexical)一词表明,词法作用域根据声明变量的位置来确定该变量可被访问的位置。嵌套函数可获取声明于外部作用域的函数。这跟函数在哪里调用无关

function f1(){
    var a=2 //在此声明的变量可以被内部函数bar访问
    return function bar(){
        console.log(a)
    }
}
var f=f1()
f()
/* 以上例子尽管bar函数被返回,但仍可访问其词法作用域中的局部变量a */
循环中的闭包

来看一道经典的面试题:

function test(idx){
    console.log(idx)
}
for(var i=0;i<2;i++){
    setTimeout(() => {
         test(i)
    }, 1000);
}

该题的输出并不是0,1,而是2,2。循环中传递给延时函数的回调函数是同一个引用,共享同一个词法作用域,域中包含局部变量i,该局部变量被共享,即每次循环后都改变,延时回调之前已经处理完毕,所以连续两次输出最后的i值2。解决这个问题可以有以下两种方法:

  • 添加一个闭包
function test(idx){
    return function(){
        console.log(idx)
    }
}
for(var i=0;i<2;i++){
    setTimeout(test1(i), 1000);
}

回调函数是有函数test创建并返回的新函数,即每次循环创建了新的词法作用域,局部变量i在不同的作用域中不共享,所以不受影响,输出依次为0,1

  • 立即执行函数
function test(idx){
    console.log(idx)
}
for(var i=0;i<2;i++){
   (function(i){
        setTimeout(() => {
            test(i)
        }, 1000);
    })(i)
}

JS中调用函数传递参数都是值传递 ,所以当立即执行函数执行时,首先会把参数i的值复制一份,然后再创建函数作用域来执行函数,即i不是共享的变量

总结

当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数时,就产生了闭包。即产生闭包的条件是:1.函数嵌套;2.内部函数引用了外部函数的数据(变量或函数)

相关文章

  • swift-闭包

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

  • 闭包,闭包,闭包

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

  • 闭包-Closures [swift 5.1]

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

  • Day7 闭包(Closures)

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

  • Python闭包

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

  • 闭包(closure)

    ● 闭包基础 ● 闭包作用 ● 闭包经典例子 ● 闭包应用 ● 闭包缺点 ● 参考资料 1、闭包基础 作用域和作...

  • swift- 闭包一

    /*• 闭包表达式• 尾随闭包• 值捕获• 闭包是引用类型• 逃逸闭包• 自动闭包*/

  • (9) python之闭包

    闭包闭包 = 函数 + 环境变量(函数定义的时候) 一个最简单的闭包 闭包不受外部变量影响 非闭包 闭包 闭包 只...

  • Swift-进阶 :闭包(二)逃逸闭包 & 非逃逸闭包

    本文主要分析逃逸闭包 、非逃逸闭包、自动闭包 逃逸闭包 & 非逃逸闭包 逃逸闭包定义 当闭包作为一个实际参数传递给...

  • javascript闭包详解

    跟我念 bi 闭 bao包 ,闭包的闭,闭包的包。。 闭包的简介 在计算机科学中,闭包(英语:Closure),又...

网友评论

      本文标题:闭包

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