匿名函数包装局部变量并返回新函数

时间:2012-10-10 21:23:44

标签: javascript canvas anonymous-function kineticjs

我非常抱歉再问一个匿名功能问题,但是每当我弄清楚它时,它就会变成接缝,javascript会让我失去另一个曲线球。

我正在使用KineticJS创建多个圈子,然后像这样制作动画(跟these tutorials之后)

for ( i = 0; i < rows; i++ )
{
   for ( j = 0; j < cols; j++ )
   {
      index = i * cols + j;
      circles [ index ] = new Kinetic.Circle({...});
      ...
   }
}
...
for ( i = 0; i < rows; i++ )
{
   for ( j = 0; j < cols; j++ )
   {
      index = i * cols + j;
      anims [ index ] = new Kinetic.Animation({func: function ( frame )
            {
               ( function ( innerCircle )
               {
                  ...
               } ( circles [ index ] ) );
            },
            node: layer
         }
      );
   }
}

我的目的是在创建匿名函数时传递index的当前值。问题是只有最后一个图像被动画,我无法弄清楚原因。这是full jsfiddle

1 个答案:

答案 0 :(得分:3)

您应该创建新变量范围的函数位于错误的位置。它应该在传递的函数之外,并且返回一个新函数。

返回的函数可以访问所需的值。

for ( i = 0; i < rows; i++ )
{
   for ( j = 0; j < cols; j++ )
   {
      index = i * cols + j;
      anims [ index ] = new Kinetic.Animation({func: function(innerCircle) {
                                                        return function ( frame ) {

                                                        };
                                                      })(circles[index]),
            node: layer
         }
      );
   }
}

但老实说,不要内联这样的功能。当你创建一个返回你的函数的命名函数时,它会变得非常清晰。

function makeFunc(innerCircle) {
    return function (frame) {
           // you can use innerCircle in here
    };
}

for ( i = 0; i < rows; i++ ) {
   for ( j = 0; j < cols; j++ ) {
      index = i * cols + j;
      anims [ index ] = new Kinetic.Animation({
         func: makeFunc(circles[index]),
         node: layer
      });
   }
}

有些人出于某种原因喜欢那些内联函数,但我认为它们只是增加了混乱。命名函数会稍微分解代码,并在代码中添加一些文档。

此外,它稍微高效一点,因为你没有在循环的每次迭代中创建一个新的内联函数。相反,你正在重复使用同一个来构建处理程序。