使用Class方法作为回调时如何存储侦听器引用?

时间:2018-03-01 21:23:30

标签: javascript

我正在使用ES6类定义来创建小组件,在其他事物之间,将侦听器附加到元素。由于我将类方法绑定为侦听器回调,因此我在事件执行期间使用.bind()来保留上下文。

为了澄清,我写了一篇非常有人工作的课程:

class Test {
    constructor(el) {
        this.x = 10;
        this.elem = el;

        this.elem.addEventListener('click', this.listenerFn.bind(this));
    }

    listenerFn(ev) {
        console.log(this.x);
    }
}

如果我想稍后破坏此组件并从元素中分离侦听器而不破坏元素本身,则会引发问题。由于使用.bind()创建了一个新功能,因此仅仅引用this.listenerFn是不够的。

我想到的是创建一个侦听器地图并在连接/分离时使用它们。

像这样:

class Test {
    constructor(el) {
        this.x = 10;
        this.elem = el;

        this.listenerPool = {
            'click': this.listenerFn.bind(this),
        }
        this.elem.addEventListener('click', this.listenerPool.click);

        this.elem.test = {
            destroy: this.destroy.bind(this),
        }
    }

    listenerFn(ev) {
        console.log(this.x);
    }

    destroy() {
        this.elem.removeEventListener('click', this.listenerPool.click);
        delete this.elem.test;
    }
}


//...

new Test(document.querySelector('#some_id'));

document.querySelector('#some_id').test.destroy();    

虽然它有效,但它没有利用原型方法,而是为每个类的实例创建一个新副本,所以我想知道:这是正确的吗?

如果人们可以针对同一问题分享不同的解决方案,我也将不胜感激。

1 个答案:

答案 0 :(得分:1)

您不需要整个listenerPool来执行此操作,但通常所做的是将成员方法显式绑定到constructor中的实例:

class Test {
    constructor(el) {
        this.x = 10;
        this.elem = el;

        this.listenerFn = this.listenerFn.bind(this);
        this.elem.addEventListener('click', this.listenerFn);

        // ...
    }

    listenerFn(ev) {
        console.log(this.x);
    }

    destroy() {
        this.elem.removeEventListener('click', this.listenerFn);
    }
}

您还希望避免将随机用户对象附加到elem.test = { destroy: ... }等本机对象,因为这非常类似于创建全局变量,因此请尝试从调用中找到另一种方法来调用类的destroy()方法脚本没有直接附加到元素。

我会就如何提供更具体的建议,但你没有提供调用代码。