0

I want to call a class function from within a class, which I previously attached to a button-object that resides within the class (the following code works but the scope in callMyClassFunction is on button and I want it to be the Carousel):

//Examplecode 1
Carousel.prototype.addEventListeners = function(){
    this.button.on('click', this.callMyClassFunction);
}

Carousel.prototype.callMyClassFunction = function(){
    console.log(this);
}

If I bind the function like that it works (the scope of this is the class instance):

//Examplecode 2
Carousel.prototype.addEventListeners = function(){
    this.button.on('click', function(){
        this.callMyClassFunction()
    }).bind(this);
}

But I'd rather want to add the click-eventlistener with a reference (like in Examplecode 1) since I want to call removeListener in yet another function:

//Examplecode 3
Carousel.prototype.removeEventListeners = function(condition){
    if(condition){
        this.button.removeListener('click', this.callMyClassFunction);
    }
}

Any help is much appreciated!

2 Answers 2

1

Just store the bound listener on your instance:

functin Carousel(…) {
    …
    this.callMyClassFunction = this.callMyClassFunction.bind(this);
}
Carousel.prototype.callMyClassFunction = function(){
    console.log(this);
};
Carousel.prototype.addEventListeners = function(){
    this.button.on('click', this.callMyClassFunction);
};
Carousel.prototype.removeEventListeners = function(…){
    …
    this.button.removeListener('click', this.callMyClassFunction);
};
Sign up to request clarification or add additional context in comments.

Comments

1

You can use bind rather more simply:

Carousel.prototype.addEventListeners = function(){
    this.button.on('click', this.callMyClassFunction.bind(this));
};

I'm not sure what bind you were using in your example (you were calling it on the return value of the on function), but the above uses Function#bind, which is a part of JavaScript itself (as of ES5; it's easy to shim/polyfill for older browsers). Function#bind returns a new function that, when called, calls the original function with this set to the first argument you give bind. So in the above, a click will call the function returned by bind, which will call callMyClassFunction with this set to the correct value.

If you need to use removeListener later and it requires the same function be passed into it, you'll have to remember the function, like this:

Carousel.prototype.addEventListeners = function(){
    if (!this.boundCallMyClassFunction) {
        this.boundCallMyClassFunction = this.callMyClassFunction.bind(this);
    }
    this.button.on('click', this.boundCallMyClassFunction);
};

Carousel.prototype.removeEventListeners = function(condition){
    if(condition && this.boundCallMyClassFunction){
        this.button.removeListener('click', this.boundCallMyClassFunction);
    }
};

You can't just pass it the result of calling bind again, as that would be a different function.

But check the documentation of whatever's providing the on and removeListener functions you're calling above, it may provide a simpler way to do that (jQuery does, but it doesn't look like you're using jQuery there).

2 Comments

thanks a lot, this works fine. But as for the removing of the listener I prefer Bergi's method.
Yup, that works too, provided you don't ever need that method unbound (which you frequently don't).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.