Javascript этот объект внутри интервалов / тайм-аутов - PullRequest
3 голосов
/ 12 апреля 2011

У меня есть метод, который является большой инструкцией 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)
}

Вы также можете сделать это с помощью apply или call , если вы хотите использовать this вместо cthis

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)
 }

Однако, это кажется еще хуже ...

Ответы [ 3 ]

2 голосов
/ 12 апреля 2011

Использование .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)
}

Но, боюсь, вы не станете намного лучше.

0 голосов
/ 12 апреля 2011

Я бы разбил функцию 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, []);
    }
}
0 голосов
/ 12 апреля 2011

Ваш первый пример более или менее стандартный способ сделать это. Единственное, что я могу предложить, - это назвать вашу переменную как-то иначе, чем cthis; сделайте его описательным для связываемого объекта.

Javascript 1.8.5 добавляет Function.prototype.bind для решения этой проблемы другим способом, но для большинства людей это бесполезное решение.

...