闭包closure

mandyGuan12 / 2024-09-13 / 原文

先理解:作用域、作用域链、函数作用域以及变量对象
.
.
给一段代码:

    var global;
    function a() {
        var aa = 123
        function b() {
            aa = 111
            console.log(aa)
        }
        // b()
        return b
    }
    var res = a()
    res()

本来fn a执行完后应该销毁,即作用域链断裂。但是它里面return了一个b,b的作用域链并未断裂,b在定义时,它的作用域链中是可以访问到fn a内的变量的。
此时的a函数调用和b函数生成是同一个作用域链

.

.

.
那么如何定义闭包?

闭包(Closure)可以精简凝练地定义为:一个函数以及创建该函数时所能访问的所有外部变量的组合。闭包允许一个函数访问并操作函数外部的变量,即使该函数在其外部作用域之外被调用。这种机制使得JavaScript等语言能够支持私有变量和模块化编程。

简单来说,闭包就是能够记住并访问其词法作用域(lexical scope)的函数,即使该函数在其词法作用域之外执行。

也就是说,能够读取其他函数内部变量的函数就是闭包
.
.
.
.
场景适用:

  1. 定时器传参
// 定时器传参
    function a(aa) {
        return function () {
            console.log(aa)
        }
    }

    setTimeout(() => {
        const logFunc = a(123)
        logFunc()
    }, 1000)

闭包是一个函数值,它引用了其外部作用域中的变量。在这个例子中,a函数返回的匿名函数就形成了一个闭包,因为它引用了在a函数作用域中定义的aa变量。
.
要理解,尽管a函数的执行和logFunc变量的赋值都发生在setTimeout的回调函数中,但是闭包内的aa变量仍然能够保持其值(123),并且可以被闭包内部的代码访问。这是因为闭包记住了它被创建时的作用域环境。
.
.
.

内存泄漏问题: