【问题标题】:How to use keyword this in a mouse wrapper in right context in Javascript?如何在 Javascript 的正确上下文中的鼠标包装器中使用关键字 this?
【发布时间】:2010-04-22 13:23:54
【问题描述】:

我正在尝试为鼠标行为编写一个简单的包装器。这是我当前的代码:

function MouseWrapper() {

  this.mouseDown = 0;  
  this.OnMouseDownEvent = null;
  this.OnMouseUpEvent = null;
  document.body.onmousedown = this.OnMouseDown;  
  document.body.onmouseup = this.OnMouseUp;
}

MouseWrapper.prototype.Subscribe = function (eventName, fn) {

  // Subscribe a function to the event
  if (eventName == 'MouseDown') {
    this.OnMouseDownEvent = fn;
  } else if (eventName == 'MouseUp') {
    this.OnMouseUpEvent = fn;
  } else {    
    alert('Subscribe: Unknown event.'); 
  }  
}  


MouseWrapper.prototype.OnMouseDown = function () {  
  this.mouseDown = 1;  
  // Fire event
  $.dump(this.OnMouseDownEvent);
  if (this.OnMouseDownEvent != null) {
    alert('test');
    this.OnMouseDownEvent();
  }
}

MouseWrapper.prototype.OnMouseUp = function () {

  this.mouseDown = 0;
  // Fire event
  if (this.OnMouseUpEvent != null) {
    this.OnMouseUpEvent();
  }  
}

从我收集的信息看来,在 MouseWrapper.prototype.OnMouseUp 和 MouseWrapper.prototype.OnMouseDown 中,关键字“this”并不意味着 MouseWrapper 的当前实例,而是其他东西。而且它没有指向我的实例而是如何解决问题是有道理的?

我想正确解决问题我不想使用肮脏的东西。

我的想法: * 使用单例模式(鼠标毕竟只是一个) * 以某种方式将我的实例传递给 OnMouseDown/Up - 如何?

感谢您的帮助!

【问题讨论】:

    标签: javascript events object this


    【解决方案1】:

    上述解决方案很好,但更可重用的方法是通过创建一个为您创建该闭包的方法,将您的方法“绑定”到上下文。例如

    Function.bind = function(method, context) {
      return function() {
        return method.apply(context, arguments);
      }
    }
    

    按照 Slaks 的例子,你会:

    document.body.onmousedown = Function.bind(this.OnMouseDown,this);
    document.body.onmouseup = Function.bind(this.OnMouseUp, this); 
    

    或者你可以对 Function.prototype 做语法糖。

    Function.prototype.bind = function(context) {
      return function() {
        // since this is a prototype method, "this" is the method to be called
        return this.apply(context, arguments);
      }
    }
    
    document.body.onmousedown = this.OnMouseDown.bind(this);
    document.body.onmouseup = this.OnMouseUp.bind(this); 
    

    您还可以绑定要调用的参数以及上下文...询问您是否感兴趣。

    单例方法虽然可行,但却是一种 hack。它正在添加全局变量,而不是正确解决手头的问题。这意味着如果你需要在两个地方的行为,它就行不通。

    【讨论】:

      【解决方案2】:

      在 Javascript 中,与大多数语言不同,this 关键字的值是在调用函数时确定的。

      例如:

      var dumper = function() { alert(this); };
      var str1 = "A";
      str1.dump = dumper;
      str1.dump();        //Alerts A
      
      var str2 = "B";
      str2.dump = str1.dump;
      str2.dump();        //Alerts B
      

      当浏览器调用您的事件处理程序时,它会在 DOM 元素的上下文中调用它,所以 this 不是您认为的那样。

      要解决此问题,您需要使用匿名方法在正确的上下文中调用您的处理程序。

      例如:

      var self = this;
      
      document.body.onmousedown = function(e) { return self.OnMouseDown(e); };
      document.body.onmouseup = function(e) { return self.OnMouseUp(e); };
      

      另外,你不应该处理这样的事件。

      改为call attachEvent / addEventListener

      【讨论】:

      • 设置后,您并没有使用闪亮的新 self 变量。
      • 感谢您的解释!该代码有效。我会看看链接。我不经常使用 Javascript。
      猜你喜欢
      • 1970-01-01
      • 2018-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      相关资源
      最近更新 更多