Hong Wang
Hong Wang

Reputation: 113

Confusing JavaScript nested execution result

I try following simple JavaScript nested code, while the result is confusing.

Anyone can give a detail explanation? Thanks very much.

I am waiting...

<script>
  // args = [];

  function foo (param) {
    args= [];
    if (param <= 1) {
      args.push(foo(2));
    } else {
      return param;
    }
  }

  foo(1)
</script>

The final args is [], I guess the outer args (is [2]) is overwritten by the nested inner args (which is []). Who can give a detail explanation about the result? How is the execution sequences? Thanks.

Upvotes: 0

Views: 83

Answers (3)

Hong Wang
Hong Wang

Reputation: 113

From @Dmitry, thanks.

The args is a global binding (since you don't use var). In first call foo(1), you set it to:

args -----> [];

Then you add 2 to it by a recursive call. However, when you recursively call foo it rebinding global foo identifier to a new array in memory, still keeping the old one.

args -----> []  // new array

     -----> [] // old one

So you add 2 to the old one when return from recursion:

args -----> []  // new array

     -----> [2] // old one

After exit, args is bound to the new one which is empty, and the reference to the old one is missed (it will be GC'ed).

See binding and mutation topics: http://dmitrysoshnikov.com/ecmascript/es5-chapter-3-1-lexical-environments-common-theory/#name-binding

Upvotes: 0

VinhNT
VinhNT

Reputation: 1101

your code call foo function twice 1. foo(1) is the first call, when foo run the statement

if (param <= 1) {
  args.push(foo(2)); // run here for the first call of foo 
} else {
  return param;
}

That's similar as

if (param <= 1) {
  var foo2= foo(2); // -> trigger the second call of foo
  args.push(foo2); // first element is pushed in args
} else {
  return param;
}

In second call of foo(2) param=2 then, foo2=2 on above code, Finally, you got an array with only an item and args[0]=2

EDIT:

args is not overwrite, you have declare args as local variable of foo function, then when foo(1) was called, it creates a args variable. when foo(2) is called, another args is created.

Upvotes: 1

sdfsdf
sdfsdf

Reputation: 5590

args = [];

  function foo (param) { // param is 1
    if (param <= 1) { // param <= 1 is true
      args.push(foo(2)); // so args is now [foo(2)]
    } else { // ignored
      return param;
    }
  }

  /*
    This is foo(2) is computed
    function foo (param) { // param is 2
    if (param <= 1) { // param <= 1 is false, so this if statement is ignored
      args.push(foo(2));
    } else {
      return param; // returns 2
    }
  }
  */

  foo(1) // args is [2]

Upvotes: 0

Related Questions