【问题标题】:storing arrays in closure闭包存储数组
【发布时间】:2013-03-05 05:54:24
【问题描述】:

这是使用闭包更新数组的最佳方式吗?我在另一个网站上看到了类似的东西。我想知道创建的全局变量closure1。有没有办法在不创建全局的情况下做到这一点。

<script>  
    var closure1=Closure(0, 0);

    function Closure(num, i) {
        var num=num;
        var index=i;
        var anArray = [];
        return function(num,index) {
          anArray[index]=(num);
          out.innerHTML=anArray;
        }
    } 
 </script>

<div id="d1" onclick=" closure1(2,0)">2 index 0</div>
<div id="d2" onclick=" closure1(5,3)">5 index 3</div>
<div id="d3" onclick=" closure1(4,1)">4 index 1</div>
<div id="d4" onclick=" closure1(9,7)">9 index 7</div>
<div id="out" >?</div>

【问题讨论】:

  • 传递给 Closure() 的两个参数是干什么用的?它们的值保存在返回的匿名函数永远不会使用的局部变量中。
  • 我把这些东西漏掉了,因为它与问题无关。基本上我正在从本地数组转移到闭包。实际的数组值将通过另一个函数而不是 onclick 推送到函数。
  • 好的,但是如果您没有展示更接近真实代码的内容,我们将无法回答您的“这是最好的方法吗...”的问题。内联事件属性需要全局变量,但现在您说您实际上并没有使用它们,所以...

标签: javascript arrays closures


【解决方案1】:

您需要有一种方法来调用您创建的闭包,以便在onclick 属性中使用它。将closure1 作为全局变量的优点是闭包只创建一次,您可以通过调用closure1(num, index) 在整个页面中重复使用它。但是,如果您不希望在全局范围内有一个名为 closure1 的变量,您可以通过以下方式清理

编辑:我之前发布了两种建议的方法。感谢@nnnnnn 指出其中一种方法会破坏 OP 的代码。我已删除不正确的建议并保留正确的建议。

您可以将闭包作为属性添加到现有的Closure 函数中。例如,如果你想创建一个新的闭包closure1,你应该像这样创建它

删除线:

var closure1=Closure(0, 0);

添加以下行AFTER Closure 函数已定义,如下所示:

Closure.closure1 = Closure(0, 0);

并将您的点击次数替换为

<div id="d1" onclick="Closure.closure1(2,0)">2 index 0</div>

完整的代码如下所示:

<script>  
    function Closure(num, i) {
        var num=num;
        var index=i;
        var anArray = [];
        return function(num,index) {
          anArray[index]=(num);
          out.innerHTML=anArray;
        }
    } 

    Closure.closure1 = Closure(0, 0);
 </script>

<div id="d1" onclick="Closure.closure1(2,0)">2 index 0</div>
<div id="d2" onclick="Closure.closure1(5,3)">5 index 3</div>
<div id="d3" onclick="Closure.closure1(4,1)">4 index 1</div>
<div id="d4" onclick="Closure.closure1(9,7)">9 index 7</div>
<div id="out" >?</div>

这是我认为最干净的方法。希望这会有所帮助。

【讨论】:

  • 您的选项 1 不等同于 OP 的代码,因为每个实例都有自己的数组,而不是共享同一个数组。
  • 无法让代码正常工作。 “Closure.closure1 = Closure(0, 0);”在哪里去?我在函数内部和外部都试过了。
  • @user1740058 更新了我的答案。您需要在定义闭包函数之后写
【解决方案2】:

我认为你可以做这样的事情。如果您不想创建全局变量,请将脚本包装在自执行函数中。

(function(){
      var closure1=Closure(0, 0);

      function Closure(num, i) {
        var num=num;
        var index=i;
        var anArray = [];
        return function(num,index) {
          anArray[index]=(num);
          out.innerHTML=anArray;
        }
      }
  }()); 

【讨论】:

  • 这不起作用,因为现在closure1是本地的,不能在函数之外调用
  • @user1740058 - 是的,但您的问题是关于在没有全局的情况下执行此操作,这不适用于内联事件属性。你不能同时拥有它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
  • 2017-04-10
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
相关资源
最近更新 更多