2

As below code, I make an object named "test", and give it properties and method.

The property came from its argument.

And I try to call the method every 2 sec after onload, and the result shows undefined.

But if I only call the method not using setInterval(), like this

window.onload = function() {
   giveword.showWord();
}

I'll be able to show the text "Hi".. Why is that?

var giveword = new test("Hi");

function test(word) {
    this.word = word;
}

test.prototype.showWord = function() {
    document.getElementById("msg_box").innerHTML = this.word;
}

window.onload = function() {
    setInterval(giveword.showWord, 2000);
}

Thanks for help...

Arel Lin
  • 908
  • 2
  • 13
  • 24

2 Answers2

2

The reason is because in your test.prototype.showWord function your this object is referring to the context in which the function is called, which is the window object when called from setInterval.

I think what you want to do is use a closure to make the context of showWord() be the giveword instance like this:

        var giveword = new test("Hi");

        function test(word) {
            this.word = word;
        }

        test.prototype.showWord = function() {
            document.getElementById("msg_box").innerHTML = this.word;
        }


        window.onload = function(){
            setInterval(function(){giveword.showWord();}, 2000); // <<-- here's the closure
        }

The difference is that with the closure you're telling the setInterval function to call a function within the context as it was when the setInterval was declared. When setInterval was declared there was a variable in scope called giveword that had a method showWord() that returns the value of your initial input. (Closures are hard to explain, and I'm afraid you'd be best served by someone else explaining them if you need more info.)

nickvans
  • 898
  • 13
  • 24
0

This solution this now so easy, use an arrow function in setInterval. Here is an example using setInterval inside of an object method.

const mobile = {
make: 'iPhone',
model: 'X',
battery: 10,
charging: false,
charge: function() {
    if(this.battery < 100) {
        this.charging = true;
        console.info('Battery is charging...');
        let interval = setInterval(() => {
            this.battery = this.battery + 10;
            console.info(mobile.battery);

            if( this.battery === 100){
                this.charging = false;
                clearInterval(interval);
                console.info('Battery has finished charging.');
            }
        }, 100);
    }
    else {
        console.info('Battery does not need charging.');
    }
}
}
Sambuxc
  • 425
  • 2
  • 11
  • 26