开发者

JavaScript context issue using setInterval with prototype [duplicate]

开发者 https://www.devze.com 2023-01-08 15:19 出处:网络
This question already has answers here: JavaScript setInterval and `this` solution (9 answers) Closed 3 months ago.
This question already has answers here: JavaScript setInterval and `this` solution (9 answers) Closed 3 months ago.

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;
开发者_C百科        }  

        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?


Change start to this:

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


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.


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***);
0

精彩评论

暂无评论...
验证码 换一张
取 消