I am attempting to pass function scope to a callback method. The problem I am having is that I am getting object scope, which does not provide me with access to the paramet
btw, few words about scopes in your code:
function lookup() {
var bar = 'food'; // local var
MySvcWrap.doWork('thang', myHandler, this); // this here points to window object and not to the function scope
}
so it is the same as writing:
function lookup() {
var bar = 'food'; // local var
MySvcWrap.doWork('thang', myHandler, window);
}
it is so because you define lookup function globally. inside doWork function, when you write this it points to MySvcWrap object (because that function is defined inside that object).
If your callback function has to see bar variable, it should be defined in the same scope, like that
MySvcWrap = {
doWork: function(p1, callback, scope) {
var result = {colors: ['red', 'green'], name:'Jones', what: p1};
if (callback) {
callback.call(scope||this,result, scope);
}
}
}
function lookup() {
var bar = 'food'; // local var
MySvcWrap.doWork('thang',
function (data, ctx) {
console.log('myHandler(): bar: ' + bar);
console.log(JSON.stringify(data));
},
this); // scope object is this
}
lookup();
in this case you send anonymous function as callback, it is defined inside lookup function so it has access to its local variables; my console shows me in this cae:
myHandler(): bar: food
{"colors":["red","green"],"name":"Jones","what":"thang"}
to make it easier to support, you can define myHandler inside lookup function:
function lookup() {
var bar = 'food'; // local var
var myHandler = function(data, ctx) {
console.log('myHandler(): bar: ' + bar);
console.log(JSON.stringify(data));
};
MySvcWrap.doWork('thang', myHandler, this); // scope object is this
}
On the other hand, why one function should have access to local variables of another function? Maybe it can be redesigned...
One more way to make your code working is to use anonymous function, instead of lookup (will work if you just declare and execute that function once):
(function() {
var bar = 'food';
function myHandler(data, ctx) {
console.log('myHandler(): bar: ' + bar);
console.log(JSON.stringify(data));
}
MySvcWrap = {
doWork: function(p1, callback, scope) {
var result = {colors: ['red', 'green'], name:'Jones', what: p1};
if (callback) {
callback.call(scope||this,result, scope);
}
}
}
MySvcWrap.doWork('thang', myHandler, this);
}
)();
result is the same, but no lookup function anymore...
And one more idea to make it working... Actually you need to define callback handler in the same scope where bar variable is defined, so it can be done a bit tricky, but just as alternative:
function myHandler(bar) { // actually in this case better to call it createHandler
return function(data, ctx) {
console.log('myHandler(): bar: ' + bar);
console.log(JSON.stringify(data));
}
}
MySvcWrap = {
doWork: function(p1, callback, scope) {
var result = {colors: ['red', 'green'], name:'Jones', what: p1};
if (callback) {
callback.call(scope||this,result, scope);
}
}
}
function lookup() {
var bar = 'food'; // local var
MySvcWrap.doWork('thang', myHandler(bar), this); // scope object is this
}
And few resources to read about JavaScript scoping and closure: