从事件处理程序关闭访问公共和私有方法

时间:2012-12-06 20:23:05

标签: javascript javascript-events closures private-members

我很难理解我当前的JavaScript代码是如何工作的。我设法解决了从事件处理程序关闭访问私有对象方法的问题,但我想知道它为什么会这样。

代码使用众所周知的模块/插件隐喻:

(function(module, $, undefined)
{
  function myPrivateCode(e){ /*...*/ }

  module.myPublicCode = function(e) { /*...*/ }

  module.init = function()
  {
    var that = this;
    $('.clickable').click(function(e)
    {
      if($(e.target).hasClass('classX'))
      {
         that.myPublicCode(e.target); // requires 'that' to work
      }
      else
      {
         // that.
         myPrivateCode(e.target);     // will fail if 'that' uncommented
      }
    });
  }

}(window.module = window.module || {}, jQuery ));

在代码中我设置了一个单击处理程序,它调用public或private方法。完全可以想象我们需要将对象引用传递给事件处理程序闭包,这由that局部变量完成。我感到奇怪的是,myPrivateCode既不需要that作为参考,也不会因为其“隐私”而失败。这使我认为myPrivateCode不是访问适当的对象,并且以某种方式以预期的方式工作。有人能解释会发生什么吗?当然我错过了什么。

提前致谢。

2 个答案:

答案 0 :(得分:0)

您对myPrivateCode(e.target);的调用正在您作为处理程序传递给click函数的匿名函数的上下文中运行。

有关详细信息,请阅读closures

有关更简单的示例,请尝试以下代码:

var foo = function () {
    var a = 1;

    return function (b) {
        return a+b;
    }
};

var bar = foo();

bar(1); // 2

bar(1)总是会给出2,因为创建函数时a = 1在范围内。在您的情况下,a是您的that,您的处理程序是已关闭的函数。

http://jsfiddle.net/Fh8d3/

答案 1 :(得分:0)

thatmyPrivateCode都可通过closure提供给您的事件处理程序。简而言之,正在发生的是您在另一个函数内声明的每个变量和函数都可以访问外部作用域。

另一方面,

myPublicCode无法通过闭包获得,因为它专门分配给您的module对象。因此,调用它的唯一方法是使用module.myPublicCode()(或that.myPublicCode(),但实际上并不需要that,因为module也可用)