JavaScript闭包问题请解释一下

时间:2011-03-14 02:09:37

标签: javascript

这是我试图理解的Pro JavaScript技术的功能,但不是。该功能的目的是通过在一秒钟内增加其高度来缓慢地揭示隐藏元素。代码中的注释由本书作者提供。我不明白任何从作者在评论中所说的“关闭以确保我们拥有正确的'我'。

请您尽可能详细地解释

a)这个闭包在这个函数中是如何工作的。即它如何确保它具有正确的“我”以及代码中的内容使其变得重要。

b)为什么在代码elem,.style.height

之后的程序结尾附近有逗号?

c)这部分代码的目的是什么(pos + 1)* 10)。它如何与setTimeout函数一起使用?

function slideDown(elem) {
  //start the slide down at 0
  elem.style.height = '0px';

    //Show the element, but can`t see it because height is 0
   show(elem);

    //find the full potential height of the element
    var h = fullHeight(elem);

   //We`re going to do a 20 frame animation that takes place over one second
   for (var i = 0; i <= 100; i +=5 ) {
         //a closure to make sure that we have the right 'i'
         (function() {
           var pos = i;

          //set the timeout to occur at the specified time in the future
          setTimeout(function() {

            //set the new height of the element
             elem,.style.height = (pos/100) * h) + "px";

         }, ( pos + 1) * 10);
       })();
     }
}

4 个答案:

答案 0 :(得分:3)

a)由于setTimeout()电话,这是必不可少的。由于setTimeout()在逻辑上是睡眠线程,因此可以在下一次循环迭代后调用,i在调用setTimeout()的主体时可能是不同的值。 “保存”i作为pos修复此潜在问题,并在i同时更改pos时保护其值。现在,i的值完全由高级确定,并且不受主线程(正在递增setTimeout的循环)的更改。

b)不知道,看起来像是一个错字。 编辑:是的,这是一个错字。你去吧。

c)确保i的身体在未来时间与setTimeout(..., 10)的值成比例。想一想;如果每个调用都是pos,那么一切都将在10ms开始,但仍然以执行循环的任何速度执行。在此值中添加setTimeout作为一个因素会“减慢”未来setTimeout()调用的执行速度。与评论一样,它确保未来{{1}}次调用以每秒20次的速度发生(创建20FPS动画效果)

答案 1 :(得分:1)

你没有一个正确的闭包来定义你认为的i的正确值。你几乎已经建好了......试试这个......

   (function(index) {
       var pos = index;

      //set the timeout to occur at the specified time in the future
      setTimeout(function() {

        //set the new height of the element
         elem.style.height = ((pos/100) * h) + "px";

     }, (pos + 1) * 10);
   })(i);

通过将i作为参数传递给函数,它将在执行中传递当前值,index将具有正确分配的值。

修改

想要添加此good explanataion of closures and references in javascript

答案 2 :(得分:1)

a)当你在i上进行迭代时,它假装在回调中使用,当调用回调时,i的值将是最后一个i到达。创建一个闭包,你创建一个i的副本(因为它是一个基本类型),在内存中有另一个位置。这样做,当调用回调时,它将使用闭包的实例。

不同之处在于,在内存中,您只有一个i,但是有pos的N个实例(以及N个闭包范围),所以当setTimeout回调开始时,它将会引用用于定义它的闭包的特定范围。

b)听起来像是一个错字。

c)这是以毫秒为单位的延迟时间。在算法中,它似乎会在10毫秒时触发第一个元素的大小调整,第二个元素在20分钟时调整,依此类推。

此函数的作用如下:setTimeout(callback, milliseconds),函数可以是匿名的,因此setTimeout(function() { ... }, 10)是一种有效的语法。

祝你好运!

答案 3 :(得分:1)

c)此代码触发一系列创建动画的setTimeout调用。 (pos + 1)* 10代码确保每个setTimeout比它之前的那个稍晚发生,从而错开每个调用,这是动画发生的原因。