访问"这个"来自原型中的事件

时间:2015-01-01 14:46:32

标签: javascript scope closures hammer.js

考虑以下代码......使用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时似乎。方法,“这个”是未定义的,好像它以某种方式失去了范围?

我会喜欢解决方案和解释。谢谢!

2 个答案:

答案 0 :(得分: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");
}

答案 1 :(得分:2)

你可以绑定"这个"像这样的事件回调:

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

当事件触发回调时,它应该具有正确的"此"。