理解 JavaScript 闭包

2025-06-10

理解 JavaScript 闭包

替代文本

这确实是一个很难理解的概念,我花了一段时间才理解闭包是什么。以下是我理解的闭包,并附上一些图表和代码片段,以便更好地理解。

为了热身,我将从一个不涉及闭包的示例开始,然后慢慢将我的示例更改为最后涉及闭包

function add1(){
  var x = 1;
  var f = function(y){
    return x + y;
  }
  return f(3);
}

console.log(add1());
Enter fullscreen mode Exit fullscreen mode

这里我们有一个简单的函数叫做add1

  • 它有一个局部变量x,其值为1
  • 另一个f被赋予函数的变量
  • add1函数返回函数f

因此,如果我们运行此代码,它将返回4= x1 和y= 3

由于我们有一个函数声明,并且该函数在 console.log 中被调用。执行上下文如下:

替代文本

首先,我们将进入global execution context创建阶段。我们将进入creationandexecution阶段。在这个creation阶段,我们将add1函数提升到作用域的顶部;在这个execution阶段,我们将执行add1函数。

调用该add1函数将创建add1执行上下文,如下所示:
替代文本

在这个执行上下文中,我们将在阶段提升变量x和 ,并且在 阶段它们都是未定义的。在阶段,被赋值被赋值给接受参数 的函数。赋值后,它返回 函数调用fcreationcreationexecutionx1fyf(3)

替代文本

这会创建另一个名为 f 的执行上下文。在f执行上下文中,由于没有声明任何变量或函数,因此在创建阶段我们不会提升任何内容。在执行阶段,它会返回,x+y其中 的值x是通过执行上下文中的作用域链获取的add1,而 的值y是通过以下方式传入的:f(3)

因此总体x而言是1y3。返回4。每个 EC 执行完成后,都会将其逐一弹出堆栈。

让我们看一下作用域链
替代文本

在执行上下文中f,它返回的是x+y。 的值y在此上下文中是可获取的,即 的值3,但 的值x不是。因此,它引用外部执行上下文并检索 的值,x1


呼……真是太多了。希望你能够理解执行上下文和作用域。现在我们准备继续讨论一些更复杂的东西,它与闭包有关。以下是代码片段

var add = function() {
  var x = 1;
  var f = function(y) {
    return x + y;
  };
  return f;
};

var g = add();
console.log(g(3));
Enter fullscreen mode Exit fullscreen mode

add这个例子与第一个不同,我们现在返回的是函数的引用而不是值。然后,我们在函数调用时在函数作用域之外调用了该函数g(3)。这部分可能比较难理解。

让我们再回顾一下执行上下文,看看它是如何运作的。首先是全局执行上下文

替代文本

接下来是add执行上下文

替代文本

现在到了最有趣的部分。一旦add执行上下文完成执行,它将被弹出堆栈。

替代文本

接下来是 g(3) 执行上下文。记住,该变量g包含函数f,因为它是 function 中返回的函数add

替代文本

所以g会返回x + y。我们正在运行g(3)所以的值y将是 3。
的值呢x

好吧,如果我们四处寻找,我们将无法找到x。但我们记得在另一个已创建、执行并弹出的执行上下文中,它x被设置为。1

因此Javascript,如果一个函数在另一个函数(例如)内部创建g,那么g它将保留对封闭函数范围内变量的引用(在本例中)add。这意味着g仍然可以访问add包含变量的执行上下文的内存x

替代文本

基本上,add执行上下文已经结束,但g仍然允许访问仍在执行上下文内存中的执行上下文的变量add

尽管它不再位于执行堆栈中,我们的函数g仍然可以沿着作用域链向上爬并找到它。x

g's执行上下文有closed in x一个 ,即使x's执行上下文消失了,它仍然是一个外部变量。所以我们的函数g是一个closure

像函数这样的闭包g在内部存储对外部变量的引用。

让我们看一下这个的作用域链
替代文本

我们有全局执行上下文范围。我们将拥有addg变量以及它们的执行上下文。

var g = add();完成后,添加执行上下文将从堆栈中弹出。(由于这个原因,它被阴影化了)

然后我们创建并执行执行上下文。即使执行上下文不再位于堆栈中,g它仍然可以引用外部变量。xx's


希望你通过本文对闭包有了一定的了解。如果你仍然感到困惑,请阅读以下参考资料。

这是我用来进一步理解这个主题的主要参考资料
执行上下文的终极指南

鏂囩珷鏉ユ簮锛�https://dev.to/yaminmhd/understanding-javascript-closures-1fk7
PREV
如何将 Cookie 同意横幅和 Cookie 政策添加到您的网站
NEXT
Web3 教程:构建类似 OpenSea 的 NFT 市场 DApp