1

I'm trying to get my head round this context problem while using prototypal inheritence (which I've not really played with before). I have an AutoScroller object:

function AutoScroller() {  
    this.timer = null;  
}  

AutoScroller.prototype = {

    stop: function() {
        if (this.timer == null) {
            return;
        }  

        clearInterval(this.timer);
        this.timer = null;
        console.log("stop");
    },  

    start: function() {
        if (this.timer != null) {
            return;
        }
        this.timer = setInterval(function() { this.move(); }, 3000);
        console.log("start");
    },

    move: function() {
        console.log("move");
    }

};

On document ready, I initiate everything by doing this:

var scr = new AutoScroller();  
$('div.gallery p.stopBtn').bind("click", scr.stop);  
$('div.gallery p.startBtn').bind("click", scr.start);  

The problems all arise because "this" always refers to 'p.startBtn' and not scr, so when the start function with setInterval is called I'm getting an error "this.move() is not a function".

I know context is a fairly fundamental concept of which I appear to have no idea. Any ideas on how to sort this out?

user399050
  • 61
  • 1
  • 3

3 Answers3

0

Change start to this:

start: function() {
    if (this.timer != null) {
        return;
    }
    var that = this;
    this.timer = setInterval(function() { that.move(); }, 3000);
    console.log("start");
}
Chris Laplante
  • 29,338
  • 17
  • 103
  • 134
  • Unfortunately I've already tried this approach - after executing the line "var that = this", that = p.startBtn (still!) – user399050 Jul 22 '10 at 13:28
  • Sorry, this was actually correct. However, it needed to be used in conjunction with a closure on the button click event which I've put on here. Thanks for your reply. – user399050 Jul 22 '10 at 14:31
0

I finally worked it out... I used a closure in the button click like this:

var scr = new AutoScroller();
$('div.gallery p.startBtn').bind('click', function(x) {
    return function() {
        x.start();
    }
}(scr));

And also implemented the change mentioned by SimpleCoder above.

user399050
  • 61
  • 1
  • 3
0

You can also pass the current object instance in setInterval method, so that it always has the access to 'this'.

Verified on IE11, Chrome, Opera and Firefox.

setInterval(function (objRef) {              
        objRef.foo();
    }, 500, ***this***);
1JD
  • 345
  • 3
  • 5