Reputation: 101
For example I have this function with a closure:
function getData() {
var status = 0;
var func = function() {
status++
alert(status);
}
return func;
}
Its works correctly and the variable "status" is visible within the closure function.
But if I transfer the closure code into the separate function the closure variable "status" isn't available:
function getData() {
var status = 0;
var func = function() {
myFunction();
}
return func;
}
function myFunction() {
status++
alert(status);
}
Yes, I can send this variable to the function and then return the changed value. But what if I need recursion in "myFunction"?
function getData() {
var status = 0;
var a = function() {
myFunction(status);
}
return a;
}
function myFunction(status) {
if (status == 0) {
status = 1;
// After calling this function again "status" will reset to 0,
// but I want to save current value (status = 1).
data();
}
return status++;
}
var data = getData();
data();
How can I get one instance of my variable "status" for all calls to the closure function.
Thanks!
Upvotes: 2
Views: 311
Reputation: 664650
If I transfer the closure code into the separate function the closure variable "status" isn't available.
True, and that won't change due to JavaScript's scoping rules.
Yes, I can send this variable to the function and then return the changed value. But what if I need recursion in "myFunction"?
Nothing changes. You can use recursion from inside the closure as well.
function getData() {
var status = 0;
function data() {
if (status++ == 0) {
// do anything you want
// including recursive calls to `data()`
}
return status;
}
return data;
}
getData()();
Upvotes: 0
Reputation: 4530
You could replace this line:
myFunction(status);
with:
status = myFunction(status);
or:
JSFIDDLE: http://jsfiddle.net/KHZRr/
function Data(){
var status = 0;
var a = {
getData : function(){
if( status == 0 ){
status = 1;
return "FIRST, status = " + status;
}else{
return "NOT FIRST, status = " + status;
}
}
}
return a;
}
var data = Data();
alert( data.getData() );
alert( data.getData() );
alert( data.getData() );
Is this what you are looking for?
Upvotes: 1
Reputation: 222198
Firstly, that doesn't work because JS has lexical scopes, not dynamic scopes. More info on Wikipedia
Secondly, if you want to pass in a variable to a function, and allow that function to mutate it, you need to send something that's an instanceof
Object.
0 instanceof Object
false
"" instanceof Object
false
[] instanceof Object
true
({}) instanceof Object
true
(function(){}) instanceof Object
true
You can wrap your number into an object and pass it.
Modified example:
function getData() {
var o = {
status: 0
};
var a = function () {
myFunction(o);
}
return a;
}
function myFunction(o) {
console.log(o);
if (o.status == 0) {
o.status = 1;
// After calling this function again "status" will reset to 0,
// but I want to save current value (status = 1).
data();
}
return o.status++;
}
var data = getData();
data();
Output:
Object {status: 0}
Object {status: 1}
http://jsfiddle.net/Dogbert/Tw7nh/
Upvotes: 2