在 JavaScript 中,闭包的实际用途是什么?

2022-08-29 23:47:32

我正在我最大的努力来理解JavaScript的闭包。

我通过返回内部函数得到,它将可以访问其直接父级中定义的任何变量。

这对我有什么用?也许我还没有完全理解它。我在网上看到的大多数例子都没有提供任何现实世界的代码,只是模糊的例子。

有人可以向我展示封闭式的真实世界使用情况吗?

例如,这个是吗?

var warnUser = function (msg) {
    var calledCount = 0;
    return function() {
       calledCount++;
       alert(msg + '\nYou have been warned ' + calledCount + ' times.');
    };
};

var warnForTamper = warnUser('You can not tamper with our HTML.');
warnForTamper();
warnForTamper();

答案 1

假设您要计算用户单击网页上按钮的次数

为此,您正在触发一个函数 onclick 事件 of button 来更新变量的计数

<button onclick="updateClickCount()">click me</button>

现在可能有很多方法,例如:

  1. 您可以使用全局变量和函数来增加计数器

     var counter = 0;
    
     function updateClickCount() {
         ++counter;
         // Do something with counter
     }
    

    但是,陷阱是页面上的任何脚本都可以更改计数器,而无需调用 updateClickCount()。


  1. 现在,您可能正在考虑在函数中声明变量:

     function updateClickCount() {
         var counter = 0;
         ++counter;
         // Do something with counter
     }
    

    但是,嘿!每次调用函数时,计数器再次设置为 1。updateClickCount()


  1. 正在考虑嵌套函数

    嵌套函数可以访问“上面”的作用域。

    在此示例中,内部函数可以访问父函数中的计数器变量:updateClickCount()countWrapper()

     function countWrapper() {
         var counter = 0;
         function updateClickCount() {
             ++counter;
             // Do something with counter
         }
         updateClickCount();
         return counter;
     }
    

    这可以解决计数器困境,如果你可以从外部访问函数,你还需要找到一种方法,只执行一次,而不是每次都执行。updateClickCount()counter = 0


  1. 关闭救援!(自调用功能)

     var updateClickCount = (function(){
         var counter = 0;
    
         return function(){
             ++counter;
             // Do something with counter
         }
     })();
    

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

    这种方式成为一种功能。“美妙”的部分是它可以访问父范围中的计数器。updateClickCount

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

    受匿名函数的作用域保护,并且只能使用该函数进行更改!counterupdateClickCount()

关于闭包的更生动的例子

<script>
var updateClickCount = (function(){
    var counter = 0;

    return function(){
        ++counter;
        document.getElementById("spnCount").innerHTML = counter;
    }
})();
</script>

<html>
<button onclick="updateClickCount()">click me</button>
<div> you've clicked
    <span id="spnCount"> 0 </span> times!
</div>
</html>

参考:JavaScript 闭包


答案 2

我使用闭包来做这样的事情:

a = (function () {
    var privatefunction = function () {
        alert('hello');
    }

    return {
        publicfunction : function () {
            privatefunction();
        }
    }
})();

正如你所看到的,现在是一个对象,有一个调用的方法( ),它只存在于闭包内部。您不能直接拨打(即 ),只是.apublicfunctiona.publicfunction()privatefunctionprivatefunctiona.privatefunction()publicfunction()

这是一个最小的例子,但也许你可以看到它的用途?我们用它来强制实施公共/私有方法。