Reputation: 38228
I tried this and it always show 1 time, something's wrong, how to fix this ?
function myFunc() {
var increment = (function() {
var i = 0;
return function() {
i++;
return i;
};
})();
alert(`calling myFunc ${increment()} times`);
}
Upvotes: 1
Views: 102
Reputation: 130
The issue is that when a variable goes out of scope it is destroyed, the next time a value is called it will be recreated, and initialized at whatever value it starts as. As the variable i
is scoped to inside the increment
function, which is itself scoped to myFunc
it means that when myFunc
that closure is destroyed and will be created the next time the function is run.
An example that shows i
hoisted to be in myFunc
's scope and the increment
function running several times.
function myFunc() {
console.log('running myFunc');
var i = 0;
console.log('assigning i to ' + i);
function increment() {
console.log('incrementing');
i++;
};
increment();
increment();
console.log(`calling myFunc ${i} times`);
}
myFunc();
Notice that i
now maintains its state across calls to increment
. Now when we call myFunc
multiple times, we see that i
is destroyed, then a new variable is created when myFunc
is run again.
function myFunc() {
console.log('running myFunc');
var i = 0;
console.log('assigning i to ' + i);
function increment() {
console.log('incrementing');
i++;
}
increment();
increment();
console.log(`calling myFunc ${i} times`);
}
myFunc();
myFunc();
Now if we hoist i
up to be above the scope of myFunc
we'll see that it's value is kept within scope across calls to myFunc
.
var i = 0;
console.log('assigning i to ' + i);
function myFunc() {
console.log('running myFunc');
function increment() {
console.log('incrementing');
i++;
}
increment();
console.log(`calling myFunc ${i} times`);
}
myFunc();
myFunc();
Upvotes: 1
Reputation: 5779
Any time you call my func it's going to redefine the increment function, so you shouldn't expect it to ever say anything other than 1
. Your problem is that increment is being defined on every call to myFunc
What you want to do is this:
var i = 0;
function myFunc() {
var increment = (function() {
return function() {
i++;
return i;
};
})();
alert(`calling myFunc ${increment()} times`);
}
So now i
will keep its values between calls to myFunc
. It'll have to be outside myFunc
. Or you can move the whole function outside of myFunc
.
var increment = (function() {
var i = 0;
return function() {
i++;
return i;
};
})();
function myFunc() {
alert(`calling myFunc ${increment()} times`);
}
Now this works:
console.log(increment()); // logs 1
console.log(increment()); // logs 2
Upvotes: 2
Reputation: 8060
Works for me.
var increment = (function() {
var i = 0;
return function() {
i++;
return i;
};
})();
console.log(increment());
console.log(increment());
console.log(increment());
Upvotes: 0