for循环

时间:2015-05-04 19:11:11

标签: javascript function for-loop recursion

var f_drum_min = function myself(a){
  alert(a);
  $f_min_node.push(a);
    for (i=0;i<=$m;i++){
      if ($f_leg[i][1]==a){
          myself($f_leg[i][0]);
      }
    }  
};

myself($f_leg[i][0]);打破for循环,如何让它在循环中多次运行?

2 个答案:

答案 0 :(得分:4)

Your function is riddled with bad habits

There's no way for me to improve this function because I have no idea what all of those external states do. Nor is it immediately apparent what their data types are.

These are bad habits because there's no possible way to know the effect of your function. Its only input is a, yet the function depends on $f_min_node, $f_leg, and $m.

  • What is the value of those variables at the time you call your function?

  • What other functions change those values?

  • I assigned $f_min_node to some value and then called f_drum_min. How was I supposed to know that $f_min_node was going to get changed?

Every time you call your function, it's a big surprise what happens as a result. These are the woes of writing non-deterministic ("impure") functions.

Until you can fix these problems, recursion in a for-loop the least of your concerns

I have annotated your code with comments here

// bad function naming. what??
var f_drum_min = function myself(a){

  // side effect
  alert(a);

  // external state: $f_min_node
  // mutation: $f_min_node
  $f_min_node.push(a);

    // leaked global: i
    // external state: $m
    for (i=0;i<=$m;i++){

      // external state: $f_leg
      // loose equality operator: ==
      if ($f_leg[i][1]==a){
          myself($f_leg[i][0]);
      }
    }  
};

I can help you write a deterministic recursive function that uses a linear iterative process though. Most importantly, it doesn't depend on any external state and it never mutates an input.

// Number -> Number
var fibonacci = function(n) {
  function iter(i, a, b) {
    if (i === 0)
      return a;
    else
      return iter(i-1, b, a+b);
  }
  return iter(n, 0, 1);
}

fibonacci(6); // 8

for loops are pretty primitive; Imperative programmers will reach for it almost immediately thinking it's the only way to solve an iteration problem.

I could've used a for loop in this function, but thinking about the problem in a different way allows me to express it differently and avoid the for loop altogether.

答案 1 :(得分:2)

One basic problem with the code, which would cause it to break under almost any circumstances, is that the loop variable i is a global, and is thus shared by all recursive invocations of the function.

For example, let's say the function is invoked for the first time. i is 0. Now it recurses, and let's say that the condition in the if is never true. At the end of the 2nd call, i = $m + 1. When you return to the first call, because i is global, the loop in the first call ends. I assume this is not what you want.

The fix for this is to declare i as local:

for (var i=0;i<=$m;i++){

This may or may not fix all of your problems (as pointed out in comments, we'd have to see more of your code to identify all possible issues), but it is a critical first step.