【问题标题】:When to use recursive function?什么时候使用递归函数?
【发布时间】:2013-12-23 21:16:46
【问题描述】:

我正在阅读有关递归函数的信息,我读到当我们使用递归函数时,它会调用堆栈帧,因此如果我们最终调用递归函数 10000 次,则可能是可用内存的问题。我在下面有一个函数使用递归是否正确?或者你认为我应该避免它?

function animateLeft(obj, top){
   if(top >= 300){         
       obj.style.visibility = 'visible';
       return;  
   }
   else {
       var box = obj;
       box.style.marginLeft = top + "px";
       box.style.marginTop = top + "px";
       setTimeout(function(){
           animateLeft(obj, top + 1);
       }, 25) 
   }
}
function animateMe() {
    animateLeft(document.getElementById('inner-rectange'), 0);
}

【问题讨论】:

  • 我遇到了问题,我用递归解决了。
  • 指出这个问题也可以在纯 CSS 中解决
  • @simone 我正在尝试创建动画,所以我必须添加延迟,不确定如何使用 css 完成
  • @Jay,CSS 支持动画和过渡
  • 我猜 CSS3 做的对吗?

标签: javascript function recursion


【解决方案1】:

使用setTimeout意味着你的代码不是直接递归调用动画函数。这会导致函数被重复调用,但不会导致创建深栈。

对于动画来说,这是一个相当合理的方法(有更好的方法,例如requestAnimationFrame,但它是合理的!)

【讨论】:

  • 这是我正在尝试创建的动画,因此 settimeout 只会增加延迟。
  • 我不认为它是 ABA 递归的,因为堆栈中永远不会有相同的 A 函数不止一次。以这种方式使用setTimeout 只是意味着该函数将被一遍又一遍地调用,但绝不会从其自身(或它调用的某些函数 - 这会产生 ABA 递归)
  • 我已经更新了答案,我明白你的意思了。它仍然是递归的,但不会像直接调用它一样导致堆栈“增长”。
【解决方案2】:

您并没有真正使用递归,因为您是从 setTimeout 调用方法。

到函数重新执行时,初始值已经退出..(每次执行都不会阻塞下一次

在 javascript 中对操作 DOM 的事物使用递归是错误的,因为只有在整个递归完成后才会重新绘制页面。所以你将失去动画的所有中间步骤,从第一步到最后一步.


正如 cmets 中提到的问题,您可以单独使用 CSS 实现这种动画..

只需通过 CSS 设置 DOM 节点的transition property,然后通过应用新类来更改属性(或直接通过 javascript

div{
    margin-left:0;
    margin-top:0;

    -moz-transition:margin 2s linear;
    -webkit-transition:margin 2s linear;
    transition:all 2s linear;
}

.move{
    margin-left:100px;
    margin-top:100px;
}

http://jsfiddle.net/gaby/rm3EP/查看演示

当您将move 类应用到div CSS 时,会为页边距的变化设置动画......

【讨论】:

  • 这是否意味着递归函数在后台涉及,而settimeout有延迟?
  • 根据定义,超时将在您指定的时间过去后调用回调(并且不会阻止其他代码执行 i>)
  • ok 如果我删除 setTimeout 函数会怎样?它会是递归的吗?
  • @Jay,是的,那么它将是递归的,但您的动画将不会显示,因为在脚本运行时,DOM 不会更新..
  • 最好运行一个循环。当您需要函数的结果在当前运行中使用它时,可以更好地利用递归。 (循环也不会更新 DOM
【解决方案3】:

我不会使用递归来做到这一点。我什至不确定jQuery或其他东西是否会做得更好。

当我处理像树这样的递归数据结构时,我首先考虑递归,但不是这样的情况。

【讨论】:

  • 或者对象的多维数组什么的
【解决方案4】:

您的示例更像是延迟递归函数。由于 setTimeout,内存应该没有问题。当前的 animateLeft 将完成,下一个将在稍后结束。

【讨论】:

    【解决方案5】:

    我知道这已经很晚了,但我最近一直在寻找递归函数。 我最好的答案是,只有在你不知道需要运行一段代码多少次或者当你有某些类型的数据结构(如树或树)时才使用递归函数。 堆栈

    【讨论】:

      猜你喜欢
      • 2020-09-14
      • 2018-04-09
      • 2010-09-05
      • 1970-01-01
      相关资源
      最近更新 更多