2014-11-09 2 views
0

Я пытаюсь создать функцию, которая создает «прокси» вокруг метода объекта. Этот «прокси» будет использоваться для обработки веб-запросов, а затем вызова целевого метода. Функция прокси выглядит примерно так:Область переменной Javascript при динамически ссылающихся функциях

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; 
    } 
}; 

вызова прокси (с) на это возвращает прокси-объект с суммой() и умножим() функции. Однако из-за области переменной member в функции proxy() она всегда вызывает последнюю ссылочную функцию в c - в этом случае multiply().

var cProxy = proxy(c); 

//this should call c.sum, but instead calls c.multiply 
cProxy.sum({ 
    x: 3, 
    y: 8 
}); 

Как я могу ссылаться на правильную функцию в функции proxy(), чтобы вызвать правильный метод?

+0

почему вы не просто делать 'прокси [член] = с [член]'? – Markasoftware

+0

Приведенный выше код упрощен. В реальной реализации прокси-сервер будет обрабатывать веб-запросы и обрабатывать данные запроса перед вызовом исходного метода в c, так что это было бы невозможно. Я смог заставить его работать с закрытием, как показано в ответе ниже. – subeeshb

ответ

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 
+0

Спасибо, это сработало! – subeeshb

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 для привязки аргументов или контекста к функции. Это не работает, потому что вы уже используете контекст и аргументы.

+0

Спасибо! Это сработало бы. Я решил использовать другой ответ, поскольку код был бы несколько чище. – subeeshb

+0

Пока вы знаете, что это значит. Почему существует '!'? Что это за закрытие бизнеса? Почему он не работал в первую очередь. – Rudie

Смежные вопросы