首页 > 解决方案 > 在 JavaScript 中对事件调用类方法不会更改类属性

问题描述

考虑这段代码:

var states = {
  "default" : {
    foo: "foo",
    mouseReleased: function() {
      console.log("Mouse released");
      this.foo = "bar";
    }
  }
}

var canvas = function(states) {
  return {
    states: states,
    currentState: "default",
    draw: function() {
      if (this.states[this.currentState].mouseReleased != undefined) {
        window.mouseReleased = this.states[this.currentState].mouseReleased
      }
    }
  }
}

当我释放鼠标时,控制台显示“鼠标已释放”,但states.default.foo不会更改为bar. 有没有办法不使用window.mouseReleased's this?我已经阅读了一些关于 的内容bind,但我不确定它是什么意思。我在正确的地方搜索吗?

标签: javascriptp5.js

解决方案


尽管共享代码在其他方面无效且非常不寻常,但它看起来确实是一个经典的函数绑定问题。

问题是this关键字的含义在 Javascript 中有些不寻常。默认情况下,在函数体中,调用函数时this将引用点左侧的对象。因此,例如:

let objectA = {
  whoAmI: 'A',
  sayA: function() {
    console.log(this.whoAmI);
  }
};

let objectB = {
  whoAmI: 'B'
};

objectB.sayA = objectA.sayA;

// Logs 'A'
objectA.sayA();
// Logs 'B' because `this` now refers to `objectB`
objectB.sayA();

let defaultThis = objectA.sayA;
// This will log undefined because `this` defaults to the global scope, or `window`
defaultThis();

bind()您想要锁定this. 因此,如果我有一个想直接用作事件处理程序的类方法,我将需要调用bind()我想this引用的对象:

let obj = {
  state: 0,
  handler: function() { console.log(this.state); this.state++; }
}

// This logs undefined, NaN, NaN, NaN because `this` will be `window` which does not have a `state` property
window.addEventListener('click', obj.handler);
// This logs 0, 1, 2, 3
window.addEventListener('click', obj.handler.bind(obj));

同样的原则也适用于 p5.js 事件处理函数。


推荐阅读