【问题标题】:Accessing "this" from event in prototype从原型中的事件访问“this”
【发布时间】:2023-04-04 16:37:01
【问题描述】:

考虑以下代码...使用 Hammer.js,但我认为这可能是一个通用的 Javascript 问题:

var drawLayer = new DrawLayer(document.getElementById('canvasContainer'));

function DrawLayer(targetElement) {
    this.foo = "bar";

    this.gestureDetection = new Hammer.Manager(targetElement);
    this.gestureDetection.add(new Hammer.Pan({
            direction : Hammer.DIRECTION_ALL,
            threshold : 0
        }));
    this.gestureDetection.add(new Hammer.Press({
            time : 0,
            threshold : 5
        }));
    this.gestureDetection.on("press", this.drawBegin);
    this.gestureDetection.on("panmove", this.drawMove);
    this.gestureDetection.on("panend pressup", this.drawEnd);

    this.drawBegin("INIT TEST");
}

DrawLayer.prototype.drawBegin = function (gestureData) {
    console.log(typeof(this.foo));
    console.log("DRAW BEGIN!");
}

DrawLayer.prototype.drawMove = function (gestureData) {
    console.log(this.foo);
    console.log("DRAW MOVE!");
}

DrawLayer.prototype.drawEnd = function (gestureData) {
    console.log(this.foo);
    console.log("DRAW END!");
}

当我第一次运行它时,我得到了这个,正如预期的那样:

string
DRAW BEGIN!

但是当实际处理手势时(即通过事件调用绘图内容时),我得到:

undefined
DRAW BEGIN!

更多到这一点 - 似乎在处理任何这些 drawBegin/etc 时。方法,“this”是未定义的,好像它以某种方式失去了范围?

我想要一个解决方案和一个解释。谢谢!

【问题讨论】:

  • this 的值取决于函数的调用方式。不要将obj.drawMove 直接传递给事件处理程序注册函数,而是传递一个匿名包装函数,该函数通过对象引用调用drawMove

标签: javascript scope closures hammer.js


【解决方案1】:

您可以像这样将“this”绑定到事件回调:

this.gestureDetection.on("press", this.drawBegin.bind(this));

当回调被事件触发时,它应该有正确的“this”。

【讨论】:

    【解决方案2】:

    “this”的值取决于调用函数的方式。

    在第一种情况下,您直接从 DrawLayer 类调用 drawBegin 函数:

    this.drawBegin("INIT TEST");
    

    在这种情况下,此变量表示 DrawLayer obj。

    当你通过事件调用函数时

    this.gestureDetection.on("press", this.drawBegin);
    

    “this”变量可以被函数“on”包裹以表示其他任何东西(通常是事件本身或触发事件的对象)。

    尝试将您的代码更改为以下内容,看看它是否有效:

    function DrawLayer(targetElement) {
        this.foo = "bar";
    
        this.gestureDetection = new Hammer.Manager(targetElement);
        this.gestureDetection.add(new Hammer.Pan({
                direction : Hammer.DIRECTION_ALL,
                threshold : 0
        }));
        this.gestureDetection.add(new Hammer.Press({
                time : 0,
                threshold : 5
        }));
        this.gestureDetection.on("press", this.drawBeginWrapper);
        this.gestureDetection.on("panmove", this.drawMove);
        this.gestureDetection.on("panend pressup", this.drawEnd);
    
        var _self = this;
    
        this.drawBeginWrapper = function(gestureData) {
              _self.drawBegin(gestureData);
        } 
    
        this.drawBegin("INIT TEST");
    }
    

    【讨论】:

      猜你喜欢
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多