2011-06-09 23 views
1

我定義我的課像這樣:JavaScript類方法

function Slot(slot, maxSpeed, timer) { 
this.slot = slot; 
this.speed = 0; 
this.maxSpeed = maxSpeed; 
this.timer = timer; 
this.interval = null; 

this.go = function() { 
    var $slot = $(this.slot); 
    console.log(this.slot); 
    $slot.addClass('motion'); 
    $slot.spStart(); 

    this.interval = window.setInterval(function() { 
     var step = Math.floor(Math.random() * ((this.speed/100) * 25)) + 1; 
     if (this.speed < (this.maxSpeed/2)) { 
      this.speed += step; 
     } 

     if (this.speed >= (this.maxSpeed/2)) { 
      this.speed -= step; 
     } 
     console.log(this.slot); 
     $slot.spSpeed(this.speed); 
    }, timer); 
}; 

$(this.slot).pan({ fps: '30', dir: 'down' }); 
$(this.slot).spStop(); 
} 

第一的console.log返回預期值,但一旦我進入了setInterval函數的所有變量(this.slot,this.speed)都未定義?儘管我仍然在他們的範圍內......

回答

2

作用域是有點怪習慣在Javascript中,甚至當你開始使用的setInterval和setTimeout的離奇

在你的情況下,這是在區間內引用匿名函數本身。您可以分配「這個」匿名函數之外的另一個變量:

var self = this; 
this.interval = window.setInterval(function(){ /* use self here instead of this*/} 

,或者你可以在間歇步驟調用該對象上的功能:

this.interval = window.setInterval(this.callback, timer); 
1

您的陳述「即使我仍在其範圍之內」是不正確的。 'this'變量總是被設置爲功能上下文,其中函數執行,而不是其中定義的。在這種情況下,setInterval內部的函數正在從窗口範圍執行,而'this'實際上是窗口。

要解決這個問題,我建議使用終止:(注意添加了「自我」的變量,並更換嵌套「這」與「自我」

function Slot(slot, maxSpeed, timer) { 
    var self = this; 
    this.slot = slot; 
    this.speed = 0; 
    this.maxSpeed = maxSpeed; 
    this.timer = timer; 
    this.interval = null; 

    this.go = function() { 
     var $slot = $(self.slot); 
     console.log(self.slot); 
     $slot.addClass('motion'); 
     $slot.spStart(); 

     self.interval = window.setInterval(function() { 
      var step = Math.floor(Math.random() * ((self.speed/100) * 25)) + 1; 
      if (self.speed < (self.maxSpeed/2)) { 
       self.speed += step; 
      } 

      if (self.speed >= self.maxSpeed/2)) { 
       self.speed -= step; 
      } 
      console.log(self.slot); 
      $slot.spSpeed(self.speed); 
     }, timer); 
    }; 

    $(self.slot).pan({ fps: '30', dir: 'down' }); 
    $(self.slot).spStop(); 
} 
1

沒有要求,因爲this指。裏面setInterval別的東西,你會需要像現在這樣定義的靜態副本:

this.go = function() { 
    var $slot = $(this.slot); 
    console.log(this.slot); 
    $slot.addClass('motion'); 
    $slot.spStart(); 

    var that = this; 

    this.interval = window.setInterval(function() { 
     var step = Math.floor(Math.random() * ((that.speed/100) * 25)) + 1; 
     if (that.speed < (that.maxSpeed/2)) { 
      that.speed += step; 
     } 

     if (that.speed >= (that.maxSpeed/2)) { 
      that.speed -= step; 
     } 
     console.log(that.slot); 
     $slot.spSpeed(that.speed); 
    }, timer); 
}; 
1

這很簡單,把

var self = this; 

到this.go,和定時器功能evrywhere自替換此 -

this.go = function() { 
    var $slot = $(this.slot); 
    console.log(this.slot); 
    $slot.addClass('motion'); 
    $slot.spStart(); 
    var self = this; 

    this.interval = window.setInterval(function() { 
     var step = Math.floor(Math.random() * ((self.speed/100) * 25)) + 1; 
     if (self.speed < (self.maxSpeed/2)) { 
      self.speed += step; 
     } 

     if (self.speed >= (self.maxSpeed/2)) { 
      self.speed -= step; 
     } 
     console.log(self.slot); 
     $slot.spSpeed(self.speed); 
    }, timer); 
}; 

`

1

當的setInterval()執行它這樣做外類背景的回調方法,以「這個」並不是指你的類。您必須將您的課程「this」引用作爲參數傳遞給您的回調。

var that = this; 
setInterval(function() { 
    that.someVar ... 
    that.someMethod() ... 
});