2011-06-09 92 views
2

我注意到一些我無法解釋的東西。我製作了這個增加或縮小藍色框的JavaScript代碼。腳本在這裏:Javascript setInterval question

var animated = { 

    timer : null, 

    el : document.getElementById("divNavyBox"), 

    startGrowAnimation : function() { 

     this.stopAnimation(); 

     this.timer = setInterval(

      animated.doAnimation(5), 10); 

    }, 

startShrinkAnimation : function() { 

    this.stopAnimation(); 

    this.timer = setInterval(function() { 

     animated.doAnimation(-5); 

    }, 10); 

}, 

stopAnimation : function() { 

    clearInterval(this.timer); 

}, 

doAnimation : function(amount) { 

    var size = this.el.offsetWidth; 



    if ((amount > 0 && size < 200) || (amount < 0 && size > 0)) { 

     this.el.style.width = size + amount + "px"; 

     this.el.style.height = size + amount + "px"; 

    } else { 

     this.stopAnimation(); 

    } 

} 

}; 

當調用動畫類的startGrowAnimation方法時,盒子會直觀地增長,直到它達到一定的寬度和高度。然後停止。 startGrowAnimation代碼如下所示:

startGrowAnimation : function() { 
    this.timer = setInterval(function() { 
     animated.doAnimation(5); 
    }, 10); 
} 

此代碼運行得很好。但是,我不明白爲什麼有必要在參數中放置一個匿名函數,而不僅僅是普通的調用函數。所以,我取代了代碼上面代碼如下:

startGrowAnimation : function() { 

    this.stopAnimation(); 

    this.timer = setInterval(animated.doAnimation(5), 10); 

}, 

當我使用此代碼,出於某種原因,盒子大小隻有通過每次startGrowAnimation方法被調用五個像素增加。

那麼,爲什麼在這種情況下需要在一個匿名函數調用中包含startGrowAnimation方法呢?

+0

+1 - 偉大的,發人深省的問題! – jmort253 2011-06-09 06:04:03

回答

4

您嘗試的代碼將調用該函數並將返回傳遞給setInterval()。這顯然不是你想要的。

如果您將animated.doAnimation(對函數的引用)作爲回調參數,則該函數內部的this值將指向window,而不是對象本身。這是因爲它已經失去了被稱爲該對象方法的上下文。

所以你必須調用該方法作爲對象的屬性。這意味着您需要使用匿名函數包裝器,因此其正文可以是animated.doAnimation()

唯一的另一種方式不值得一提,因爲它調用了eval()類型的函數。

+0

+1 - 很好的回答!是的,eval絕對不值得一提。可能不值得提及*這不值得一提。我確信有人會去查找eval的功能並嘗試使用它) – jmort253 2011-06-09 06:03:05

+0

這解釋了很多。然而,仍有一件事仍令我困惑。你解釋了當它不在匿名函數內時,「this」屬性指向窗口對象而不是所需的對象。每次我調用startGrowAnimation而沒有在匿名函數中包裝doAnimation語句時,它仍然會增長五個像素。它只是一次而不是連續的。這仍然不完全對我有意義... – idungotnosn 2011-06-09 06:12:49

+0

@Michael它可能是非常混亂:)發生了什麼是你*調用*函數,**不**傳遞給它的引用。它的返回值作爲第一個參數(在這個例子中是'undefined')傳遞給'setInterval()'。 – alex 2011-06-09 06:14:09