我正在尝试了解javascript中的闭包,我遇到了以下示例:
function counter() {
var count = 0;
return function() {
alert(count++);
}
}
var count = counter();
count();
count();
count();
这对我有意义,我的问题是,为什么这不起作用?
var count = function() {
var count = 0;
return function() {
alert(count++);
}
};
count();
count();
count();
对我来说,它似乎应该是完全相同的东西,但也许我只是遗漏了一些明显的东西,请帮忙。
答案 0 :(得分:2)
为了让你的第二种方法起作用,你需要像这样调用返回的函数:
var count = function() {
var count = 0;
return function() {
alert(count++);
}
};
count()();
但是,执行此操作时,您的计数不会增加,因为它不会像第一个示例中那样存储,其中变量count
保存函数。
因此,如果您想保留count的值,请使用您说var count = counter()
希望能够解决问题!
答案 1 :(得分:1)
我会尝试在您的代码中提供一个很好的解释:
function counter() {
var count = 0;
// By calling the function counter (adding a '()' after its name) you are returning a brand new anonymous function
return function() { // **Reference 1**
alert(count++);
}
}
// Here, the count variable is actually the anonymous function you returned in the **Reference 1**
var count = counter();
// In this line, you are calling the anonymous function (adding the '()' after its new name 'count')
count();
上面的解释解释了为什么这样做。因为,首先调用一个返回匿名函数并将其赋值给变量count的函数。然后你通过添加'()'来调用该函数。在其名称之后执行alert(count++)
现在,为什么另一个例子不起作用?我想现在很明显了:
var count = function() {
var count = 0;
return function() { // **Reference 2**
alert(count++);
}
};
// Here you are calling the count function which returns the anonymous function in the line **Reference 2**.
count(); // So, long story short, this call only returns the anonymous function.
你应该尝试添加第二个'()'之后:count()();
。这也应该有效,因为第一个'()'返回匿名函数,第二个函数执行返回的匿名函数。
希望这有帮助!
答案 2 :(得分:0)
在使用闭包之前,必须调用外部函数来创建闭包并获取返回的内部函数,然后保留返回结果,然后可以调用后续时间来使用闭包。因此,在第二个示例中,您必须调用count()
并保留它的返回结果,然后将该返回结果用于后续调用。
如果您将其更改为第二个示例(看起来与第一个示例非常相似),则第二个示例将起作用:
// log output for purposes of the snippet
function log(x) {
var div = document.createElement("div");
div.innerHTML = x;
document.body.appendChild(div);
}
var counter = function() {
var count = 0;
return function() {
log(count++);
}
};
// get the inner function and create the closure
var count = counter();
count();
count();
count();
正如您所看到的,这与您的第一个示例的不同之处在于counter
是函数表达式而不是函数定义。除了定义counter
的时间之外,第二个代码示例没有什么不同,因此实现需要相同。