Search code examples
javascriptecmascript-6ecmascript-5ecmascript-2017

Remove Listener when attached Function has Binding


Consider the following code:

class Test {

    constructor() {
        this.breakpoints = {};
    }

    add(options) {

        // Register the media query
        this.breakpoints[options.breakpoint] = window.matchMedia(options.breakpoint);

        // Register the listener
        this.breakpoints[options.breakpoint].addListener(this.breakpoint.bind(this));

    }

    remove(options) {
        this.breakpoints[options.breakpoint].removeListener(this.breakpoint.bind(this));
    }

    breakpoint() {
        // Do something...
    }
}

In the above code, you will notice that I am attaching an event listener in the add method, and attempting to remove it in the remove method. Due to the code in the breakpoint method, the bind(this) part is absolutely crucial.

As a result of the bind(this) (I believe), the removeListener is not removing the media query listener. Is there any way to solve this?

I have also tried this (without the bind on remove):

remove(options) {
    this.breakpoints[options.breakpoint].removeListener(this.breakpoint);
}

Solution

  • One option is to bind the breakpoint method to the context of the current instance in the constructor, so that referencing this.breakpoint always refers to the bound method later:

    class Test {
        constructor() {
            this.breakpoint = this.breakpoint.bind(this);
            this.breakpoints = {};
        }
    
        add(options) {
            // Register the media query
            this.breakpoints[options.breakpoint] = window.matchMedia(options.breakpoint);
    
            // Register the listener
            this.breakpoints[options.breakpoint].addListener(this.breakpoint);
        }
    
        remove(options) {
            this.breakpoints[options.breakpoint].removeListener(this.breakpoint);
        }
    
        breakpoint() {
            // Do something...
        }
    }