3

I have defined a class in JavaScript with a single method:

function MyClass(text) {
    this.text = text;
}

MyClass.prototype.showText = function() {
    alert(this.text);
}

Then, I defined a method that acts as a handler for a click event, using jQuery:

function MyClass(text) {
    this.text = text;
    $('#myButton').click(this.button_click);
}

MyClass.prototype.showText = function() {
    alert(this.text);
};

MyClass.prototype.button_click = function() {
    this.showText();
};

When I click the button, it fails saying:

Object #<HTMLInputElement> has no method 'showText'

It seems to be that this in jQuery click event handler refers the HTML element itself, and it does not refer the instance of the MyClass object.

How can I solve this situation?

jsFiddle available: http://jsfiddle.net/wLH8J/

2 Answers 2

11

That's an expected behaviour, try:

function MyClass(text) {
    var self = this;

    this.text = text;
    $('#myButton').click(function () {
      self.button_click();
    });
}

or in newer browsers (using bind):

function MyClass(text) {
    this.text = text;
    $('#myButton').click(this.button_click.bind(this));
}

or using jquery proxy:

function MyClass(text) {
    this.text = text;
    $('#myButton').click($.proxy(this.button_click, this));
}

further reading:

Sign up to request clarification or add additional context in comments.

2 Comments

Excellent Yoshi, I'll give it a go to the $.proxy thing, it looks like the perfect solution to me, :-)
@antur123 You're welcome! The proxy is probably the safest bet regarding browser compatibility.
2

this is determined when a function is called, not when it is defined. You have copied the function to the click handler, so when it is called it isn't associated with MyClass and this isn't what you want it to be.

You need to use a closure to store the value of this in a different variable.

function MyClass(text) {
    this.text = text;
    var self = this;
    var click_handler = function () { self.button_click(); };
    $('#myButton').click(click_handler);
}

Comments

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.