torsdag den 4. december 2014

Recursion and Javascript

Dabbling a bit with Javascript these days, and stumbled across a nasty gotcha around recursion:

Consider the code

function foo(bar){
  console.log(bar);
  if (bar==2) return;

  for (i=0; i < 3; i++){
    foo(bar+1);
  }
}

Calling foo(0) will now print 0 1 2 2
Now consider:

function foo(bar){
  console.log(bar);
  if (bar==2) return;

  var i;

  for (i=0; i < 3; i++){
    foo(bar+1);
  }
}


This will print 0 1 2 2 1 2 2, which is more in line with what you would expect from recursion.

The difference stems from a peculiarity in Javascript: Undeclared variables are implicitly global, so the loop iterator in the first function - being undeclared when it is first assigned to in the loop initializer - is a global variable that will retain its value across recursions. Declaring var i in the second function makes i local, and thereby the value belongs to the local stack frame when recursing - a behavior that you would expect in most other languages.

So to make a long blogpost short: When doing recursion inside loops in Javascript, declare your loop variable before the loop - unless of course the backwards behavior of a global iterator is what you want.