4

I understand how this works when invoked on an object, but I'm having trouble understanding how this works when called from a "static" context.

Given the following HTML:

<body onload="myOnLoad()">
    <div id="someDiv">0</div>
</body>

...and this javascript:

function myOnLoad() {
    var inc = new Incrementer();
    /*** increase() works fine here, "this" refers to "inc" ***/
    inc.increase();
    inc.setOnClick();
}

function Incrementer() {
    this.value = 0;
}

Incrementer.prototype.setOnClick = function() {
    /*** increase fails to update someDiv when clicked.
         "this" is not "inc"   ***/
    document.getElementById("someDiv").onclick = this.increase;
}

Incrementer.prototype.increase = function() {
    document.getElementById("someDiv").innerHTML = ++this.value;
}

...clicking on someDiv turns it's innerHTML into NaN. I realize that this is because the onclick event is unaware of the existence of inc, but what I don't understand is how to pass 'inc' into the onclick event.

Do you know how I can access inc's variables from the context of an onclick? Or, is there a more conventional way of doing this?

I'm mostly interested in learning how I can make someDiv's onclick refer to that specific instance, inc.

touch my body
  • 1,634
  • 22
  • 36
  • If you think you know how `this` works based on experience from other languages then you don't know how it works. See: http://stackoverflow.com/questions/13441307/how-does-the-this-keyword-in-javascript-act-within-an-object-literal/13441628#13441628 – slebetman Nov 30 '15 at 05:47
  • Thanks for the insight @slebetman. As I mentioned in my very first sentence, I don't fully understand how `this` works in javascript – touch my body Nov 30 '15 at 14:59

3 Answers3

4

this refers to the context of where the function being called, e.g. in setOnClick the function this.increase will be called in the context of someDiv, so this.value would be undefined in that case.

try

document.getElementById("someDiv").onclick = this.increase.bind(this);

You may want to learn more about the property of this from here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

Natural Lam
  • 732
  • 4
  • 13
0

In event handlers, this is bound to the element that triggered the event. If you want to affix it to your this, you need to use .bind() like so:

Incrementer.prototype.setOnClick = function() {
    document.getElementById("someDiv").onclick = this.increase.bind(this);
}
Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
0

You can try another way. You can avoid to use the property prototype and pass the html element to Incrementer at the declaration :

function myOnLoad() {
    var inc = new Incrementer(document.getElementById("someDiv"));
}

function Incrementer(newElement) {
    var value = 0;
    var element = newElement;

    this.increase = function(){
        element.innerHTML = ++value;    
    }

    element.onclick = this.increase; 
}
PublicVar
  • 54
  • 4