Javascript 使用 class 方法调用的事件侦听器

Javascript event listener called with class method

所以我有以下代码:

class SquareBlock {
constructor(){
    this.startPosition = rand(1, boardHeight - 3);
    this.block = [{x: 1, y: this.startPosition}];
    this.block.push({x: 1, y: this.startPosition + 1});
    this.block.push({x: 2, y: this.startPosition});
    this.block.push({x: 2, y: this.startPosition + 1});

    document.addEventListener('keydown', () => {return this.move();}, true);

    for(var n in this.block){
        fields[getFieldId(this.block[n].x, this.block[n].y)].hasBlock = true;
        pointColor(this.block[n].x, this.block[n].y, 'blue');
    }

    this.start();
}

start(){        
    for(var n in this.block){
        fields[getFieldId(this.block[n].x, this.block[n].y)].hasBlock = false;
        pointColor(this.block[n].x, this.block[n].y, 'transparent');
    }
    for(var n in this.block){
        this.block[n].x += 1;
    }
    for(var n in this.block){
        fields[getFieldId(this.block[n].x, this.block[n].y)].hasBlock = true;
        pointColor(this.block[n].x, this.block[n].y, 'blue');
    }

    if(this.isSettledValidate() != 'stop'){
        setTimeout(() => {this.start()}, 100);
    }
}

isSettledValidate(){
    if(this.block[2].x == boardWidth - 2 || this.block[3].x == boardWidth - 2){
        return 'stop';
    }
    if(fields[getFieldId(this.block[2].x + 1, this.block[2].y)].hasBlock == true){
        return 'stop';
    }
    if(fields[getFieldId(this.block[3].x + 1, this.block[3].y)].hasBlock == true){
        return 'stop';
    }
}

move(ev){
    switch(ev.which){
        case 37:
        for(var n in this.block){
            if(this.block[n].y - 1 != 0){
                this.block[n].y -= 1;
            }
        }
        break;
        case 39:
        for(var n in this.block){
            if(this.block[n].y + 1 != boardHeight - 1){
                this.block[n].y += 1;
            }
        }
        break;
    }
}

}

而且我在构造函数中遇到 document.addEventListener 问题。我想要实现的是使用 move() class 方法将 SquareBlock 向左或向右移动一个 space。当我使用代码 "document.addEventListener('keydown', move, true)" 时,方块不会移动,因为移动函数中的 "this" 指向 "document" 对象。当我尝试使用箭头函数修复此问题时(如上面的代码所示),"this" 正确指向方形对象但随后它也不会移动,因为方形对象没有 "which" 属性 而且我不能用它来扫描键码。如果这是简单解决方案的愚蠢问题,请原谅我,但我是新手程序员。我已经在事件处理程序中阅读了相关主题,但我在那里找不到答案。

this 的值在 javascript 中发生变化,这可能会造成混淆。查看 apply and call 以获取在调用方法时操纵 this 值的示例。在您的示例中,您可以像这样设置一个变量来表示您当前的 SquareBlock 实例:

var me = this;
document.addEventListener('keydown', () => {return me.move();}, true);

这里的推理(至少根据我的理解)是事件是从不同的上下文(文档)中引发的。通过将 this 设置到变量 me 中,您可以稍后参考该上下文。

当前设置的最快快速修复是在箭头函数中传递事件参数:e => this.move(e):

document.addEventListener('keydown', e => this.move(e), true);

用于测试的简化示例:

class SquareBlock {
  constructor(){
      document.addEventListener('keydown', e => this.move(e), true);      
  }

  move(ev){
    console.log(this , ev);
  }
}

new SquareBlock();

或者,您可以bind函数:

document.addEventListener('keydown',this.move.bind(this), true);