【问题标题】:Javascript variable scope in addEventListener anonymous functionaddEventListener 匿名函数中的 Javascript 变量范围
【发布时间】:2010-12-19 06:53:48
【问题描述】:

当点击每个 div 时,如果点击了 div 1,它应该提示“1”,如果点击了 div 2,它应该提示“5”。我试图让这段代码尽可能简单,因为这是一个更大的应用程序所需要的。

<html>
<head>
<style type="text/css">
#div1 { background-color: #00ff00; margin: 10px; padding: 10px; }
#div2 { background-color: #0000ff; margin: 10px; padding: 10px; }
</style>
<script type="text/javascript">

function init()
{
  var total = 1;

  var div1 = document.getElementById('div1'),
      div2 = document.getElementById('div2');

  var helper = function(event, id)
  {
      if (event.stopPropagation) event.stopPropagation();
      if (event.preventDefault) event.preventDefault();

      alert('id='+id);
  }

  div1.addEventListener('click', function(event) { helper(event, total); }, false);

  total += 4;

  div2.addEventListener('click', function(event) { helper(event, total); }, false);

}

</script>
</head>

<body onload="init();">

<div id="div1">1</div>
<div id="div2">2</div>

</body>
</html>

感谢您的帮助! :-)

【问题讨论】:

    标签: javascript html scope anonymous-function


    【解决方案1】:

    问题是事件监听器和'total'都存在于同一个作用域(init())

    事件函数总是会在 init() 范围内引用总计,即使在声明事件函数后它被更改

    为了解决这个问题,事件函数需要在自己的范围内有一个不会改变的“总数”。您可以使用匿名函数添加另一层范围

    例如:

    (function (total) {
        div1.addEventListener('click', function(event) { helper(event, total); }, false);
    }(total));
    
    total += 4;
    
    (function (total) {
      div2.addEventListener('click', function(event) { helper(event, total); }, false);
    }(total));
    

    匿名函数将 init() 的当前“总”值作为参数传递。这会为匿名函数的作用域设置另一个“总计”,因此 init() 的总计是否更改并不重要,因为事件函数将首先引用匿名函数的作用域。

    编辑:

    另外,你需要在辅助函数的右大括号后放置一个分号,否则脚本会报错'event'未定义。

    var helper = function(event, id)
    {
      if (event.stopPropagation) event.stopPropagation();
      if (event.preventDefault) event.preventDefault();
    
      alert('id='+id);
    };
    

    【讨论】:

    • 啊。因此,total 实际上变得像一个变量指针,很像 C++ 中的变量*?
    • 实际上,它正在被复制到本地范围内。如果它是一个指针,那么它会在范围内和范围外发生变化,这会让你回到原来的问题。
    • @Gary Matt 的示例是正确的,这里有一些术语供您参考。由于称为“闭包”(jibbering.com/faq/faq_notes/closures.html)的东西,您遇到了您的特定问题,这是 JavaScript 的一个强大而强大的功能。 Matt 向您展示的是如何使用匿名函数和一种称为柯里化的技术绕过闭包属性(有时会妨碍您)。见ejohn.org/blog/partial-functions-in-javascript 和stackoverflow.com/questions/1413916。
    【解决方案2】:

    这几乎是一样的,但我认为它会更好:

    div1.addEventListener('click', function(t){ return function(event) { helper(event, t); }}(total), false);
    

    代替:

    (function (total) {
        div2.addEventListener('click', function(event) { helper(event, total); }, false);
    }(total));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-13
      • 1970-01-01
      • 2015-09-20
      • 1970-01-01
      相关资源
      最近更新 更多