前两天写一个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);
    }
}