Javascript关闭返回函数

时间:2016-03-01 03:57:24

标签: javascript closures

我正在尝试了解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();

对我来说,它似乎应该是完全相同的东西,但也许我只是遗漏了一些明显的东西,请帮忙。

3 个答案:

答案 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的时间之外,第二个代码示例没有什么不同,因此实现需要相同。