javascript - 不完全理解这个闭包是如何工作的

标签 javascript function closures

我摘录自 How do JavaScript closures work?

我很难理解闭包。

 <button type="button" id="bid">Click Me!</button> 
 <script>
 var element = document.getElementById('bid');
element.onclick = (function() {
    // init the count to 0
    var count = 0;

    return function(e) {  // <- This function becomes the onclick handler
        count++;          //    and will retain access to the above `count`

        if (count === 3) {
            // Do something every third time
            alert("Third time's the charm!");

            //Reset counter
            count = 0;
        }
    };
})();

调用之间如何保存“计数”值?不应该在每次调用时通过 var = 0 重置它吗?

最佳答案

在回答您的问题之前,首先让我们讨论一下您的代码是如何工作的:

当你在另一个函数中定义一个函数时,它会创建一个clouser。在clouser内,内部函数可以访问外部函数范围,我的意思是外部函数的 变量参数即使外部函数已返回。在您的代码中,外部函数是 immediately-invoked-function .这意味着它在定义后立即被调用。当它返回时,内部函数被分配给onclick事件。click函数可以访问,也可以修改外部函数的变量(在本例中为 count 这是在外部函数中定义的) 即使它返回了。 我已经在你的代码中注释掉了,你看一下就清楚了

首先,立即调用的函数 (function(){...})() 将立即调用。它返回另一个函数。所以剩下的是一个返回的函数,该函数将被分配给onclik 处理程序。 所以,返回后将会是

 var element = document.getElementById('bid');
    element.onclick =function(e) {  // <- This returned function has becomes the onclick handler
            count++;          //  it can access the outer function's count variable and modify it even if the outer function returns.

            if (count === 3) {
                // Do something every third time
                alert("Third time's the charm!");

                //Reset counter
                count = 0;  // it can also reset outer function's count variable to zero
            }
        };

How is 'count' value save between invokations? Should not it be reset every invokation by var = 0?

对。如果您一次又一次地使用此代码以及立即调用的函数,每次计数都会从零开始。但是如果您您可以看到它的美妙之处>不断点击同一个按钮。即使外部函数返回,内部函数也可以访问其变量。因此每次单击按钮时它们都会被修改

第一次单击按钮将打印 1,因此计数现在为 1。 第二次单击将再次修改它并打印 2 等等。请记住,即使外部函数返回,内部函数也可以访问外部函数的变量。因此,内部函数没有任何计数变量。它只是访问外部作用域的变量。因此,第三次单击后,它将再次分配为零。<​​/p>

 var element = document.getElementById('bid');
 var mydiv=document.getElementById('mydiv');

element.onclick = (function() {

// init the count to 0
var count = 0;

return function(e) {  // <- This function becomes the onclick handler
    count++; 
   mydiv.innerHTML+=count+'</br>';		//    and will retain access to the above `count`

    if (count === 3) {
        // Do something every third time
        mydiv.innerHTML +="Third time's the charm!</br>";

        //Reset counter
        count = 0;
    }
};
})();
 <button type="button" id="bid">keep clicking me </button> 
   <div id='mydiv'></div>

关于javascript - 不完全理解这个闭包是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28225138/

相关文章:

javascript - JavaScript 中 "decorator function"和 "decorator design pattern"有什么区别?

javascript - FullScreen 在点击时有效,但在加载时无效

javascript - Imgur 上传添加到输入表单

javascript - 使 onclick 与数组一起使用

groovy - 在闭包中引用 Map 类型的属性时出错

javascript - 如何使用 ngAnimate 平滑滚动?

c - 对函数调用的 undefined reference ?

javascript - Extjs/Javascript - 在函数返回之前等待 MessageBox 响应

coldfusion - 在 cffunction 中使用 ListFilter 的可能性

ios - 闭包执行