Polymer 2.0:为什么在命令式添加监听器时需要匿名函数

Polymer 2.0: why do we need an anonymous function when imperatively adding listener

在 Polymer 2.0 (https://www.polymer-project.org/2.0/docs/devguide/events#imperative-listeners) 的新文档中,它给出了以下示例:

ready() {
  super.ready();
  this.addEventListener('click', e => this._myClickListener(e));
}

强制添加事件侦听器。如果您想删除监听器,我们必须执行以下操作(根据文档):

constructor() {
  super();
  this._boundListener = this._myLocationListener.bind(this);
}

connectedCallback() {
  super.connectedCallback();
  window.addEventListener('hashchange', this._boundListener);
}

disconnectedCallback() {
  super.disconnectedCallback();
  window.removeEventListener('hashchange', this._boundListener);
}

从表面上看,这对我来说很有意义;我们需要确保为 remove 和 add 事件侦听器传递对函数的相同引用,因为这是它索引不同侦听器的方式。

但是,为什么我们必须使用.bind(this)?我理解 returns 一个新函数,它将函数绑定到任何 "this" 是什么,所以对保存的函数进行新引用很有用,这样我们就可以添加和删除相同的函数引用。

但是为什么我们不能用第一个例子来做呢?第一段代码中的 this._myClickListener(e) 不是也有一个不会改变的唯一函数引用,我们可以引用它来添加和删除侦听器吗?为什么我们首先需要将它包装在一个匿名函数中?我觉得这样可以解决在第二段代码中详细解决的问题,但这样做显然是有原因的。

感谢您提前提供任何帮助或建议!

当您将对象的方法作为参数传递给 function/method 时,它超出了其自然上下文(this 未附加到原始对象),这就是为什么,仍然使用它就好像它是对该对象上的方法的常规调用,您使用 bind 显式绑定上下文和 returns 函数绑定到该上下文。

如果您将 this._myClickListener 作为回调传递,则不会使用您想要的 this 值调用它,因为触发调用的是 DOM 实现它,它不会知道你的 thisthis 将只是全局对象(或 undefined 在严格模式下)。

然后您可以说,好的,我将使用 this._myClickListener.bind(this)this 绑定到它,但现在您没有对那个当场创建的函数的引用。当尝试调用 removeEventListener 时,您无法使用 this._myClickListener.bind(this) 访问它,因为它只是再次创建了一个新函数,这不是您之前使用的函数。

所以,除了将绑定函数赋值给一个变量,并在addEventListenerremoveEventListener中都使用该变量之外别无他法:这是满足这两个条件的唯一方法同时:

  • 你有函数的引用
  • 函数绑定到正确的 this