我尝试学习这个概念,但我不确定返回。目前在我看到的示例中(其中许多看起来像下面的)这是关闭,但我不明白为什么我应该返回计数器,它是强制性的,否则它不是关闭?
function makeCounter() {
var count = 0;
function counter() {
count = count + 1;
return count;
}
return counter;
}
像这样
function makeCounter() {
var count = 0;
function counter() {
count = count + 1;
return count;
}
}
更新- makeCounter 仍然关闭
function makeCounter() {
var count = 0;
function counter() {
count = count + 1;
return count;
}
return counter;
var count2 = 0;
function counter2() {
count2 = count2 + 1;
return count2;
}
}
最佳答案
在您的具体示例中,您必须返回本地函数 counter 才能创建闭包。
在第二个代码示例中,makeCounter()
没有返回任何内容,因此没有创建闭包。事实上,makeCounter()
甚至不执行任何操作,因为 counter()
从未被调用。
如果您看看第一个示例中的 makeCounter()
的使用方式,就会像这样:
var myCntr = makeCounter();
var firstCnt = myCntr();
var secondCnt = myCntr();
仅从预期的用法来看,很明显 makeCounter()
必须返回一个函数才能发挥作用。
当某些代码在函数本身完成执行很久之后继续保留对函数范围内任何内容的引用时,就会创建 Javascript 中的闭包。这可以通过从第一个代码示例中的函数返回本地函数来实现。或者,当函数中包含可以在将来某个时间调用的异步回调函数或事件处理程序时,可能会发生这种情况。
<小时/>所以,在这个例子中:
function makeCounter() {
var count = 0;
function counter() {
count = count + 1;
return count;
}
return counter;
}
var myCntr = makeCounter();
仍在作用域内的 myCntr 变量和实时变量包含对内部 counter()
函数的引用,该函数又包含对 makeCounter() 中内部作用域变量的引用
。这种对内部作用域的持久引用告诉 JS 解释器和垃圾收集器,makeCounter()
本地作用域无法被垃圾收集,并且会持续存在。这个概念称为闭包。
一种对我来说很有效的简单思考方式是仅从垃圾收集的 Angular 来思考它。在 JS 中,当没有代码仍然引用该变量并且没有任何东西可以再使用该变量时,该变量就有资格进行垃圾回收。函数作用域也是如此。如果您将函数作用域视为会被垃圾收集的对象,那么只有当没有仍在运行且仍引用它的代码时,函数作用域才能被垃圾收集。返回内部函数并将该返回值存储到变量中会创建对该内部作用域的引用,因此只要该变量本身仍然处于事件状态,那么该函数作用域就无法被垃圾收集,并且将继续处于事件状态。这个概念称为闭包。它并不存在于所有语言中,但在 Javascript 中是一个非常有用的功能。
关于JavaScript 闭包;返回是强制性的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27891595/