如何在 javascript class 中逃避 "this" 问题?

How to escape "this" problem in a javascript class?

get_O3(e)
{
    e.preventDefault();

    let station = document.getElementById(e.target.id);

    let lon = station.getAttribute('lon');

    let lat = station.getAttribute('lat');

    let code_station = station.getAttribute('code');

    this.get_previsions(lon, lat, "O3").bind(this).then((data) => 
    {
        console.log(data);
    });
}

我有一个 "this" 问题,当我调用函数 get_previsions 时出现错误: 未捕获的类型错误:this.get_previsions 不是一个函数。 这可能是因为 (e) 参数,因为当我执行 console.log(this) 它 returns 目标时。我想要这个 == 我的 class。 感谢帮助

在任何给定点,您都可以通过执行以下 4 条规则来检查当前 this 引用指向的内容:

  1. New: 函数是使用 new 调用的,然后 this 指向新实例。
  2. 显式绑定:函数是使用 Function#callFunction#apply 还是 Function#bind
  3. 调用的
  4. 隐式绑定: 函数是否由其所有者调用? (即 owner.foo()owner["bar"]()
  5. 默认规则:如果 none 其他规则发生,则 this 设置为 window 对象,如果脚本是 运行 在 "use strict" 模式下,否则 undefined.

事件侦听器使用显式绑定 (callBack.call(target, ...)) 调用函数,因此 this 引用设置为目标。要更改 this 引用,您需要包装它并隐式调用它或使用 Function#bind.

隐式调用示例(+闭包):

var something = {
  foo: function() {
    var self = this;
    addEventListener("click", function(e) {
      self.bar(e);
    });
  },
  bar: function() {

  }
};

显式调用示例(函数#bind):

var something = {
  foo: function() {
    addEventListener("click", this.bar.bind(this));
  },
  bar: function() {

  }
};

我假设您的 class 定义类似于

class thing {
  get_O3(e) { ... },
  get_previsions() { ... }
}

有几个选项供您选择。第一个选项,您可以将所有函数绑定到构造函数中的 this

class thing {
  constructor () {
    this.get_03 = this.get03.bind(this);
    this.get_previsions = this.get_previsions.bind(this);
  }
  get_O3(e) { ... },
  get_previsions() { ... }
}

这可能会很尴尬,尤其是当您有很多函数时。您可以编写一个辅助 bindAll 函数,但一个 less awkward/verbose 的解决方案是使用工厂方法,完全绕过 this

function makeThing {
  const thing = {
    get_O3(e) {
      ...
      thing.get_previsions();
    },
    get_previsions() { ... }
  };
  return thing;
}

Eric Elliot on Medium 如果您想更深入地了解该主题,可以阅读一些不错的读物。