0

This code works just fine:

function whatever() {
    var s = new a('ayy');
    s.recall();
}

function a(word) {
    this.word = word;
    this.recall = function () {
        alert(this.word);
    }
}

The browser would alert the user with ayy. But why, when done like this instead:

function whatever() {
    var s = new a('ayy');
    setInterval(s.recall,1000);
}

function a(word) {
    this.word = word;
    this.recall = function () {
        alert(this.word);
    }
}

But in this instance, the alert "undefined" appears every second instead of "ayy." Why is this??

pppery
  • 3,434
  • 13
  • 24
  • 37
CLASSIFIED
  • 13
  • 5

1 Answers1

4

You are losing the proper value of this in your function because of the way setInterval() is calling it.

Change your code to:

setInterval(s.recall.bind(s),1000);

When you pass s.recall to setInterval(), that just passes a function reference and the value of s is not passed in when recall is called by setInterval(). This is true of any function reference.

If you did:

var f = s.recall;
f();

You would see the same issue. Using .bind() is a work-around to make sure that the function is called as s.recall() and thus preserves the value of s and thus the value of this inside of the recall method.


The value of this inside a function is determined by how it is called. For a method to have the right value of this, it has to be called like obj.method() or something like .bind(), .call() or .apply() has to be used in order to control the value of this. setInterval() is doing none of these. It just makes a normal function call and thus this will be either set to the global or to undefined (depending upon whether you're in strict mode or not).

See Controlling the Value of this in a function for more info on how the value of this is controlled in in a Javascript function.

Community
  • 1
  • 1
jfriend00
  • 580,699
  • 78
  • 809
  • 825