Reputation: 476
I'm trying to create a function that creates a "proxy" around an object's method. This "proxy" will be used to handle web requests and then call the target method. The proxy function looks similar to this:
var proxy = function(c) {
var proxy = {};
for(var member in c) {
var args = c[member].toString().match (/function\s*\w*\s*\((.*?)\)/)[1].split (/\s*,\s*/);
proxy[member] = function(params) {
var methodArgs = args.map(function(argName) {
return params[argName];
});
return c[member].apply(c, methodArgs);
}
}
return proxy;
};
So if I have this original controller,
var c = {
sum: function(x, y) {
return x + y;
},
multiply: function(x, y) {
return x * y;
}
};
calling proxy(c) on this will return a proxy object with sum() and multiply() functions. However, because of the scope of the member
variable in the proxy() function, it will always call the last referenced function in c - in this case, multiply().
var cProxy = proxy(c);
//this should call c.sum, but instead calls c.multiply
cProxy.sum({
x: 3,
y: 8
});
How would I reference the right function in the proxy() function so that the right method gets called?
Upvotes: 0
Views: 53
Reputation: 11807
The following worked for me, just create a closure for member
var proxy = function(c) {
var proxy = {};
for(var member in c) {
!function(member){
var args = c[member].toString().match (/function\s*\w*\s*\((.*?)\)/)[1].split (/\s*,\s*/);
proxy[member] = function(params) {
var methodArgs = args.map(function(argName) {
return params[argName];
});
return c[member].apply(c, methodArgs);
}
}(member)
}
return proxy;
};
console.log( cProxy.sum({x: 3,y: 8})) // returns 11
console.log( cProxy.multiply({x: 3,y: 8})) //returns 24
Upvotes: 1
Reputation: 53781
One way is to wrap the inside of the loop in a function to create another scope. It looks weird though:
proxy[member] = (function(member) {
return function(params) {
var methodArgs = args.map(function(argName) {
return params[argName];
});
return c[member].apply(c, methodArgs);
};
})(member);
Demo: http://jsfiddle.net/rudiedirkx/t5ovkrw9/
Another way is to use let member in c
, which creates a slightly smaller scope than var
, but let
isn't in most browsers yet.
Yet another way is to use That doesn't really work, because you're already using context and arguments..bind
to stick arguments or context to a function.
Upvotes: 1