0

I have a question regarding scope chain in javascript. I have the following code:

var num = 10;
function addFunction(num){
    var fun = function(num2) {
        return num + num2;
    }
    num++;
    return fun;
}
console.log(addFunction(5)(5));

I am not sure why it will print 11 in the console. can someone help me with that? i thoug that it will print 15. though i'm having hard time to understand the scope of the function.

Thanks

2
  • 1
    num is a parameter of the addFunction, and is local to there. The num in the fun will refer to that (incremented) variable; the global num is shadowed. Commented Jan 29, 2015 at 17:54
  • var num = 10; doesnt effect function. and function call addFunction(5)(5) . ; / whats happend is : 1) first call addFunction(5) return fun and if num++ its mean 5++ = 6. -> 2) second call addFunction(5)(5) calling fun(5) { // and return 6+5} Commented Jul 14, 2015 at 4:11

3 Answers 3

2

By what logic would it print 15? Ah, I see.

The line

var num = 10;

is irrelevant. Inside addFunction num is the parameter variable that is captured by the anonymous function assigned to fun. By the time fun was called, parameter num had been incremented by 1 and become 6.

Sign up to request clarification or add additional context in comments.

4 Comments

though the function it self is being called in the global scope without any relation to addFunction that was used only for the creation of the function fun.
is it a question? Inside anonymous function, 'num' is the 'num' closest to the function code, which is the num parameter of addFunction.
@itzikos: Well, yes. That's how it works. The scope in which a function is called has never influenced the scope chain. The scope chain is fixed when the function is created .
@Igor: 116611 didn't last long, someone upvoted me :-( I better wait till 222222.
1

about why you got console.log(addFunction(5)(5)) == 11 see my answer above.

And

if you want call console.log(addFunction(5)(5)) and get 10, you can use this solutions:

//other solutin

function tickF(n) {

 var y = function(m) {
  return f(m+n);
 }, f = arguments.callee;
 y.toString = y.valueOf = function () {
  return n;
 };
 return y;
}

console.log('no memory leak', String(tickF(1)(2)(3)), String(tickF(1)(2)(3)))

answer 6, 6

or with closure, but this solutoin you cant call second time, cause total variable wasnt reset after call-chain complete:

//chain call fn()()()
var tick = (function(){
  var total = 0;
  function fnGenerator(arg) {
    total += arg;
    return  arguments.callee;
  }

  fnGenerator.toString = function(){ return total;}
  return fnGenerator;

})()

console.log('memory leak', String(tick(1)(1)), String(tick(1)(1)))

you will get answer n console: 2, 4

see all solutions here : https://github.com/miukki/es5-bind/blob/master/tick.js

Comments

0

There is an internal function object F initialized by fun when the control comes to the fun function expression. F.[[scope]] is set to LexicalEnvironment of addFunction's execution context. You can simply consider LexicalEnvironment as an object keeping all variables with value in current scope. Here it keeps num with it's value. So before fun is returned, num is set to 6 in F.[[scope]].

Later on when you call by fun(5), what happens behind is num is retrieved from F.[[scope]] which is 6 and fun is actually called by F.call

For more on scope chain in JavaScript, there is an awesome post here: http://hujiale.me/2015/01/31/scope-the-most-important-thing-in-javascript/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.