我正在尝试创建一个围绕对象方法创建“代理”的函数。此“代理”将用于处理Web请求,然后调用目标方法。代理功能看起来类似于:
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;
};
所以,如果我有这个原始控制器,
var c = {
sum: function(x, y) {
return x + y;
},
multiply: function(x, y) {
return x * y;
}
};
对此调用代理(c)将返回具有sum()和multiply()函数的代理对象。但是,由于proxy()函数中member
变量的范围,它总是调用c中最后引用的函数 - 在这种情况下,乘以()。
var cProxy = proxy(c);
//this should call c.sum, but instead calls c.multiply
cProxy.sum({
x: 3,
y: 8
});
我如何在proxy()函数中引用正确的函数,以便调用正确的方法?
答案 0 :(得分:1)
一种方法是将循环内部包装在函数中以创建另一个范围。虽然看起来很奇怪:
proxy[member] = (function(member) {
return function(params) {
var methodArgs = args.map(function(argName) {
return params[argName];
});
return c[member].apply(c, methodArgs);
};
})(member);
演示:http://jsfiddle.net/rudiedirkx/t5ovkrw9/
另一种方法是使用let member in c
,它创建的范围略小于var
,但let
尚未在大多数浏览器中使用。
另一种方法是使用这不起作用,因为你已经在使用上下文和参数。.bind
将参数或上下文粘贴到函数中。
答案 1 :(得分:1)
以下对我有用,只需为会员创建一个闭包
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