Wie funktionieren JavaScript-Abschlüsse?
P粉494151941
2023-08-22 10:16:45
<p>Wie kann man Abschlüsse jemandem erklären, der das Konzept von JavaScript-Abschlüssen (z. B. Funktionen, Variablen usw.) versteht, aber Abschlüsse selbst nicht versteht? </p>
<p>Ich habe mir die Scheme-Beispiele auf Wikipedia angesehen, aber leider haben sie nicht geholfen. </p>
在JavaScript中,每个函数都维护着与其外部词法环境的链接。词法环境是一个作用域内所有名称(例如变量、参数)及其值的映射。
所以,每当你看到
function
关键字时,该函数内部的代码可以访问在函数外部声明的变量。这将输出
16
,因为函数bar
闭包了参数x
和变量tmp
,它们都存在于外部函数foo
的词法环境中。函数
bar
与其与函数foo
的词法环境的链接一起,构成了一个闭包。函数不需要 返回 来创建一个闭包。仅通过声明,每个函数都会闭包其封闭的词法环境,形成一个闭包。
上述函数也将输出 16,因为
bar
中的代码仍然可以引用参数x
和变量tmp
,尽管它们不再直接在作用域内。然而,由于
tmp
仍然存在于bar
的闭包中,它可以被递增。每次调用bar
时,它都会递增。闭包的最简单示例是:
当JavaScript函数被调用时,会创建一个新的执行上下文
ec
。除了函数参数和目标对象之外,该执行上下文还接收到调用执行上下文的词法环境的链接,这意味着在外部词法环境中声明的变量(在上面的示例中,即a
和b
)可以从ec
中访问。每个函数都创建了一个闭包,因为每个函数都有与其外部词法环境的链接。
请注意,闭包中可见的是变量本身,而不是副本。
闭包是以下内容的配对:
词法环境是每个执行上下文(堆栈帧)的一部分,它是标识符(即局部变量名)和值之间的映射。
JavaScript中的每个函数都保持对其外部词法环境的引用。当函数被调用时,此引用用于配置创建的执行上下文。此引用使函数内部的代码能够“看到”在函数外部声明的变量,无论函数何时何地被调用。
如果一个函数是由另一个函数调用的,那么就会创建一系列对外部词法环境的引用。这个链条被称为作用域链。
在下面的代码中,
inner
与调用foo
时创建的执行上下文的词法环境形成了闭包,闭包包含变量secret
: