2

我正在尝试了解闭包并正在查看 W3Schools javascript 教程。这是他们通过制作计数器给出的一个例子。

<body>

<p>Counting with a local variable.</p>

<button type="button" onclick="myFunction()">Count!</button>

<p id="demo">0</p>

<script>
var add = (function () {
    var counter = 0;
     return function () {return counter += 1;}
})();

function myFunction(){
    document.getElementById("demo").innerHTML = add();
}
</script>

</body>

示例解释变量 add 被赋予一个自调用函数的返回值。

自调用函数只运行一次。它将计数器设置为零 (0),并返回一个函数表达式。

这样 add 就变成了一个函数。“精彩”的部分是它可以访问父范围内的计数器。

这称为 JavaScript 闭包。它使函数可以具有“私有”变量。

计数器受匿名函数的作用域保护,只能使用 add 函数更改。

注意 闭包是一个可以访问父作用域的函数,即使在父函数关闭之后也是如此。

解释还不错,但有几件事不清楚。为什么自调用函数是最好用的?为什么嵌套匿名函数不是自调用函数?当计数器已经在其中返回时,为什么还要返回整个匿名函数?

4

1 回答 1

1

闭包的概念可以解释为具有函数及其上下文。上下文在某种程度上是一种附加到函数的存储,用于解析捕获的变量(因此命名为闭包?)。

执行示例代码时:

var add = (function () {
    var counter = 0; // This is promoted to the below's function context
    return function () {return counter += 1;}
})();

您创建一个上下文,其中counter变量被提升为匿名函数上下文,因此您可以从当前范围访问该变量。

这张图或多或少地解释了它:

JS 函数和上下文

在这种情况下,X 和 Y 由函数上下文捕获,并在该函数的所有执行中进行。

现在,这只是词法环境的 V8 实现。

请参阅 Vyacheslav Egorov 关于使用 V8 实现闭包的精彩解释:Grokking V8closures for fun (and Profit?)

于 2016-02-26T18:14:23.947 回答