Reputation: 6749
How can I get this function to pass by reference with this code?
var Class = function() {
var callback1;
var callback2;
function buildStuff(data, callback) {
element.onclick = function() {
doStuff(callback);
};
}
function doStuff(callback) {
callback();
}
return {
"setCallback1":function(fn) {
callback1 = fn;
},
"setCallback2":function(fn) {
callback2 = fn;
},
//may rebuild with different data, but same callback
"buildFoo":function(data) {
buildStuff(data, callback1);
},
//may rebuild with different data, but same callback
"buildBar":function(data) {
buildStuff(data, callback2);
}
};
}
function main() {
var object = Class();
object.setCallback1(function() {
//do stuff
});
object.setCallback2(function() {
//do something else
});
}
When you actually click on the element, callback
is undefined
. I would expect it to be the anonymous function I set it to with the setCallback
function because the user click occurs after I call the setCallback
function.
Thanks!
EDIT: Thanks for the input. I should have mentioned I need to be able to dynamically set what callback
equals. So, I can't just eliminate the callback
parameter from buildStuff
.
EDIT2: Very sorry for the confusion; I realize my example was a bit too out of context to show what I am doing. buildStuff
is actually a private member function (using the module pattern) that is called repeatedly. Depending on what is being built, it needs a different callback. The callback is actually set outside of the class (well, module pattern class), so it has to be dynamic. I've updated my code, and again, sorry for the bad example.
Upvotes: 0
Views: 92
Reputation: 75307
The click handler you create in buildStuff
creates a closure over the local variables. You pass callback
to your buildStuff
function, but at the time you pass it, it's undefined
. As this shadows the other callback
variable, you always see this value of undefined
, rather than the state of the other callback
variable.
Instead, don't pass a parameter to buildStuff
, and the closure will be created, and will capture the callback
variable you want.
function buildStuff() {
element.onclick = function() {
doStuff(callback);
};
}
Imagine this;
Your global variable callback
points to a value (in this case undefined
).
When you buildStuff
in main()
, you pass the value pointed to by callback (undefined
) as a parameter to buildStuff
Your click handler creates a closure over local variables + other variables in scope (note that the local callback
shadows the global callback
). callback
in your event handler is now undefined
.
You then setCallback
. setCallback
changes the value the global callback
variable points to using the =
operator. The global callback
and local callback
now point to different values, which is why you don't see the callback
in the event handler update.
What you want to do in this situation is to change the value pointed to by callback
, so other variables pointing there also update, but JavaScript doesn't let you do this.
Upvotes: 3
Reputation: 36438
Yes, but you've already called buildStuff
before setCallback
.
The contents of callback
at the time (undefined) will be used.
If you want to call buildStuff
with different callbacks, just do that, and eliminate the redundant setCallback
:
function buildStuff(callback) {
element.onclick = function() {
doStuff(callback);
};
}
function doStuff(callback) {
callback();
}
function main() {
buildStuff(
function() {
//do something
}
);
}
Upvotes: 2