Javascript对象中使用setTimeout和setInterval的问题
前两天写一个js时遇到个问题。就是在js对象内部如果用setTimeout或者setInterval调用该对象的一个方法,然后在被调用方法中就无法使用this获取该对象。因为经过setTimeout调用后,this就成了浏览器了,原来那个对象就丢失了。
如:
function TestObj(){
this.property = "test";
this.called = function(){
alert(this.property);
}
this.setTimeCall = function(){
setTimeout(this.called,500);
}
}
var test = new TestObj();
test.setTimeCall();
如果直接调用test.called方法是没有问题的。但如果通过setTimeout调用,也就是调用
test.setTimeCall(),this.property就为空了。因为这里的this成浏览器了。同样的问题也发生在监听浏览器的其他事件
上。没办法,于是用了个比较糟糕的办法。
function TestObj(){
this.property = "test";
this.called = function(){
alert(this.property);
}
this.setTimeCall = function(){
setTimeout("test.called()",500);
}
}
var test = new TestObj();
test.setTimeCall();
之所以说这样做糟糕,是因为在定义TestObj时,就必须提前知道TestObj被创建时的变量名。后来在IBM社区看到一篇探讨javascript有限状态机的文章,用了一个很巧妙的办法避免这个问题。
function TestObj(){
this.property = "test";
var self = this;
this.called = function(){
alert(self.property);
}
this.setTimeCall = function(){
setTimeout(self.called,500);
}
}
var test = new TestObj();
test.called();
test.setTimeCall();
在TestObj中定义一个变量,self,然后指向this。这样用self调用this,就不会发生和浏览器的this对象冲突的问题了。
虽然是很简单的一个问题,但有时候人脑子转不过弯也没办法。
还有一个网友评论提供的办法就是:
function TestObj(){
this.called = function(){
alert("OK");
}
this.setTimeCall = function(){
setTimeout(this.called.bind(this),500);
}
}