2011-06-09 72 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