Here are the codes:
function fn() {
var x = 1;
function fn2() {
x++;
console.log(x);
}
return fn2;
}
var foo = fn();
var bar = fn();
foo(); //2
bar(); //2
foo(); //3
I got a problem that I can't figure out why the result is not 2 3 4.I mean,according the closure principle,foo and bar should have maintain the scope of the function fn,so I thought foo and bar have the same x.Hope you can help me solve the problem.
4 Answers 4
foo and bar don't share the same x. x gets created when fn is called. So each call to fn will create a brand new x which will be accessible by the brand defined function fn2 that will be returned.
To check that foo and bar don't share the same x, here is an example:
function fn() {
var x = 1;
function fn2() {
x++;
return x;
}
return fn2;
}
var foo = fn();
var bar = fn();
console.log("foo: " + foo());
console.log("bar: " + bar());
console.log("foo: " + foo());
console.log("foo: " + foo());
console.log("foo: " + foo());
console.log("foo: " + foo());
console.log("bar: " + bar());
Comments
You need to call the first function once and build a closure over x then return a function with a function inside.
var fn = function () {
var x = 1;
return function () {
return function () {
x++;
console.log(x);
};
};
}();
var foo = fn();
var bar = fn();
foo(); //2
bar(); //3
foo(); //4
Comments
As var x creates a private variable, it's created anew each time fn() is assigned. If you WANTED it to carry over, simply change var x to this.x:
fn = (function() {
this.x = 1;
function fn2() {
this.x++;
console.log(this.x);
}
return fn2;
});
var foo = fn();
var bar = fn();
foo(); //2
bar(); //3
foo(); //4
3 Comments
this.x will make x global. It's as if x was defined outside the fn (globally). So then we are not talking about closures anymore.These two are the same call, hence 2 when you invoke them:
var foo = fn();
var bar = fn();
Both set var x=1 privately. Therefore, when you call them again foo(); //3 the inner function fn2 is the one invoked with the increment statement