I'm working on a problem that requires a recursive function and have noticed that nested executions seem to be modifying the parent's parameters:
var foo = function(ar) {
  console.log('Calling function - Array: ' + ar.toString());
  if(ar.length > 1){
    var ele = ar.pop();
    foo(ar);
    console.log('Function recursion ends - Array: ' + ar.toString() + ' Popped: ' + ele);
    return;
  } else {
    console.log('Function ends - Array: ' + ar.toString());
    return;
  }
}
foo([1,2,3]);
outputs (indentation mine):
/* Calling function - Array: 1,2,3 Calling function - Array: 1,2 Calling function - Array: 1 Function ends - Array: 1 Function recursion ends - Array: 1 Popped: 2 Function recursion ends - Array: 1 Popped: 3 <-- What happened to 2? */
This seems odd - because I've invoked the function with [1,2,3] and I'd expect the first iteration of the function to still maintain all of the elements provided to it between both ar and ele - but instead when the function concludes, only 1 remains in the provided array - what happened to 2? Did the nested execution pop it out of the first execution's variable?
My understanding of function scope in JavaScript would say that variables passed to a function can only modify them locally and do not export them back to the global/parent's scope as seen here:
var bar = 'bar';
function doBar(bar){
 bar = 'foo';
}
doBar(bar);
console.log(bar); //Outputs 'bar';
But the output from the recursive function seems to challenge that understanding.
How can I prevent these nested executions from modifying the parent's parameter to bring back the missing 2? Is my understanding of scoping in JavaScript wrong?
In my pathetic attempt to grasp at straws before opening this question, I've tried executing the function within a closure:
var foo = function(ar) {
  console.log('Calling function - Array: ' + ar.toString());
  if(ar.length > 1){
    var ele = ar.pop();
    (function(foo, ar){
      foo(ar);
    })(foo, ar)
    console.log('Function recursion ends - Array: ' + ar.toString() + ' Popped: ' + ele);
    return;
  } else {
    console.log('Function ends - Array: ' + ar.toString());
    return;
  }
}
But I got the same results as without using the closure - I suspect because I explictly passed in ar and foo making it no different than without the closure.
 
     
    