0

I feel like what I have is correct code, but obviously I am missing something here.

What I am trying to do is create an event method in the prototype object of my constructor. Here is what I have so far:

function Controls(but) {
    this.but = document.getElementById(but);
    this.but.onclick = function() {
        displayMessageTwo();
    }
}

Controls.prototype.displayMessageTwo = function() {
    alert("HELLO");
}

var Main = new Controls('testingTwo');

My logic here is that I am creating a constructor from which to build controls for something (let's say a slideshow).. this.but equals the html element of a link called whatever is passed as an argument to the constructor.

In my prototype object, I define my method and then create my object. However, this is not working as I had expected.

What am I doing wrong here?

3 Answers 3

2

I suspect that when the event handler fires, the context of the invocation is not the instance on which you registered the callback.

Try something like the following

function Controls(but) {
    var that = this;
    this.but = document.getElementById(but);
    this.but.onclick = function() {
        that.displayMessageTwo(); // that is closed-in
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Yup. This worked. I must've have forgot that that the onclick event returns a new function all together with a different scope. Is this the proper way to do something like this??
var that = this; is a closure by the way @SethenMaleno and yes this is pretty standard (in fact it is a must to understand closures (especially when dealing with closures that reference DOM elements as that causes memeory leaks)
I understand closures. I was just wondering if using the self = this paradigm is a good way to go about it, or if there is some other way I should be doing it.
it is one way of capturing scope that is commonly used.
2

What am I doing wrong here?

You are calling displayMessageTwo(); as if it was a global function. It is not, it is a inherited property on your instance. Usually you would refer to the instance with the this keyword, but inside the event handler you can't. Create a variable referencing the object, and call that one's method like so:

function Controls(but) {
    this.but = document.getElementById(but);

    var that = this;
    this.but.onclick = function() {
        that.displayMessageTwo();
    }
}

As your displayMessageTwo method does not care about its context (does not reference other properties via this), you even might assign it directly:

    this.but.onclick = this.displayMessageTwo;

But I'd recommend to avoid that, methods should always be executed with correct thisValue. You also might use bind:

    this.but.onclick = this.displayMessageTwo.bind(this);

but it needs additional code for older, non-supporting browsers.

2 Comments

Thanks. This does work. Is this the proper way to go about something like this?? Is there a different way that is clearer?
Yes, this is the standard way of doing it.
0

I would think:

function Controls(but) {
    this.but = document.getElementById(but);
    this.but.onclick = this.displayMessageTwo;
}

Controls.prototype.displayMessageTwo = function() {
    alert("HELLO");
}

var Main = new Controls('testingTwo');

is clearer (assigning the function assigned to prototype.displayMessageTwo). If this doesn't work it may be because

 this.but.onclick = this.displayMessageTwo;

is evaluated before:

 Controls.prototype.displayMessageTwo = function() {

making it null...

1 Comment

No, it is not evaluated before.

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.