1

I was explaining javascript closure to a friend like this:

function outer() {
 var count = 0;
 return (function(){
 count++;
 console.log(count);
 })();
}

I was trying to show him that how does this 'count' variable is stored when the outer function is executed.

So I tried doing this in the javascript console and wanted to show him that when you do this in the console

outer(); // prints out 1
outer(); // calling again prints 2
outer(); // prints out 3

but actually this happened

outer(); // printed 1
outer(); // printed 1 again
outer(); // again 1 

I don't understand whats going wrong here. Can someone guide me.

asked Jan 24, 2015 at 10:20
3
  • 2
    You probably meant to return a function. var myouter = outer(); myouter(); myouter(); myouter() Commented Jan 24, 2015 at 10:22
  • @elclanrs that works for the first time. however calling it again as myouter(); throws an error "TypeError: undefined is not a function" Commented Jan 24, 2015 at 10:30
  • 2
    outer is not returning a function, it is returning undefined. Return a function, but don't execute it and it should work. Commented Jan 24, 2015 at 10:35

3 Answers 3

2

Thanks to @elclanrs. This is the working code.

function outer() {
 var count = 0;
 return (function(){
 count++;
 console.log(count);
 });
}

Now when i call this function and store it in a variable

var myouter = outer();
myouter();
// 1
// undefined
myouter();
// 2
// undefined
myouter();
// 3
// undefined
answered Jan 24, 2015 at 10:46
Sign up to request clarification or add additional context in comments.

Comments

1

It is because your count is declared inside the function, so it is "private" to the function scope, so every time your function is called, the variable count will be created and initialized to 0 then your inner function, aka, closure increments it, that is why it prints 1, then when your closure returns, your count variable is garbage-collected because its scope ends there -- within the matching curly braces, try moving count to the outermost outside any function, then you will get what you want, then your count will become a global variable which is not good in production code because you dont want to taint your global pool, and create memory leak problem. Closures are basically just inner functions like in Java.

answered Jan 24, 2015 at 10:29

2 Comments

What I want to do is to make count private to inner function and still show him the example in this way only. Do you have a way to do that? I wanted to show him how closures is used to keep variables private to themselves. So your answer doesn't applies in this case.
You can create private variables by enclosing them in your function like you did, but to achieve what you want -- calling your function 3 times and expect your count to be 3, you cant do that since your count is scoped to the function, however you can use setTimeout() to achieve what you want.
1

You set count=0 every time you call outer(). If you want count to be private, meaning outside global scope, then I would use a module pattern like this:

var counter = (function(c){
 var count = 0;
 c.outer = function(){
 count++;
 console.log(count);
 };
 return c;
}({} || counter))
counter.outer();

or you can simply have outer() return a function:

function outer() {
 var count = 0;
 return function(){
 count++;
 console.log(count);
 };
}
var myo = outer();
myo();
myo();
myo();
answered Jan 24, 2015 at 10:41

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.