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 实现它,它不会知道你的 this
:this
将只是全局对象(或 undefined
在严格模式下)。
然后您可以说,好的,我将使用 this._myClickListener.bind(this)
将 this
绑定到它,但现在您没有对那个当场创建的函数的引用。当尝试调用 removeEventListener
时,您无法使用 this._myClickListener.bind(this)
访问它,因为它只是再次创建了一个新函数,这不是您之前使用的函数。
所以,除了将绑定函数赋值给一个变量,并在addEventListener
和removeEventListener
中都使用该变量之外别无他法:这是满足这两个条件的唯一方法同时:
- 你有函数的引用
- 函数绑定到正确的
this
在 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 实现它,它不会知道你的 this
:this
将只是全局对象(或 undefined
在严格模式下)。
然后您可以说,好的,我将使用 this._myClickListener.bind(this)
将 this
绑定到它,但现在您没有对那个当场创建的函数的引用。当尝试调用 removeEventListener
时,您无法使用 this._myClickListener.bind(this)
访问它,因为它只是再次创建了一个新函数,这不是您之前使用的函数。
所以,除了将绑定函数赋值给一个变量,并在addEventListener
和removeEventListener
中都使用该变量之外别无他法:这是满足这两个条件的唯一方法同时:
- 你有函数的引用
- 函数绑定到正确的
this