问题
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?
回答1:
Change start
to this:
start: function() {
if (this.timer != null) {
return;
}
var that = this;
this.timer = setInterval(function() { that.move(); }, 3000);
console.log("start");
}
回答2:
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.
回答3:
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***);
来源:https://stackoverflow.com/questions/3308790/javascript-context-issue-using-setinterval-with-prototype