Javascript这个对象在间隔/超时

Javascript this object inside intervals/timeouts

本文关键字:超时 对象 Javascript      更新时间:2023-09-26

我有一个方法,这是一个大setInterval语句,它需要访问this对象的对象,拥有从间隔内的方法。我实现了一个简单的闭包,但它看起来不是很优雅:

connect: function(to, rate, callback){
    var cthis = this,                             //set cthis to this,
    connectIntervalID = setInterval(function(){
        if(cthis.attemptConnect(to)){             //reference it here,
            clearInterval(connectIntervalID)
            cthis.startListening(10)              //here,
            callback && callback.apply(cthis, []) //and here
        }
    }, rate)
}
如果你想用this代替cthis ,你也可以用apply或者call
connect: function(to, rate, callback){
    var cthis = this,
    tempFunc = function(){
        if(this.attemptConnect(to)){                 
            clearInterval(connectIntervalID)
            this.startListening(10)              
            callback && callback.apply(this, []) 
         }
     }�       
     connectIntervalID = setInterval(function(){tempFunc.apply(cthis, [])}, rate)
 }

使用.bind使它更好一点(在我看来,你可能同意,也可能不同意):

支持代码:

function $A(args){
   var out = [];
   for(var i=0, l=args.length; i<l; i++){ out.push(args[i]); }
   return out;
}
Function.prototype.bind = function() {
   var __method = this, args = $A(arguments), object = args.shift();
   return function() {
      return __method.apply(object || this, args.concat( $A(arguments) ));
   };
};

,你的代码变成:

connect: function(to, rate, callback){
    connectIntervalID = setInterval((function(){
        if(this.attemptConnect(to)){             //reference it here,
            clearInterval(connectIntervalID)
            this.startListening(10)              //here,
            callback && callback.apply(this, []) //and here
        }
    }).bind(this), rate)
}

但是我担心你不会有很大的好转。

您的第一个示例或多或少是执行此操作的标准方法。我唯一的建议是给变量取别的名字,而不是这个;让它描述被绑定的对象。

Javascript 1.8.5添加了Function.prototype.bind以另一种方式解决这个问题,但这对大多数人来说不是一个有用的解决方案。

我将setInterval函数分解为它自己的函数,附加到与connect相同的对象。这样,很明显,this指的是同一个对象:

connect: function (to, rate, callback) {
    var obj = this;
    var intervalId = setInterval(function () {
        obj.connectInterval(intervalId, callback);
    }, rate);
},
connectInterval: function (intervalId, callback) {
    if (this.attemptConnect(to)) {
        clearInterval(intervalId);
        this.startListening(10);
        callback && callback.apply(this, []);
    }
}