Dynamic metaprogramming options in JavaScript?

I want to delegate several methods from one JavaScript object to another. So I thought about using metaprogramming so that several methods were not defined just like delegates. So far I have finished with this method:

function delegate_to(_method, _obj) { return function(_args) { // One parameter, what about multiple parameters? return _obj[_method](_args) } } 

So, as an example code, how it should work:

 var that = {} var delegate = {} that.foo = function(_message) { console.log("foo: " + _message) } that.bar = function(_message) { console.log("bar: " + _message) } that.baz = function(_message) { console.log("baz: " + _message) } function delegate_to(_method, _obj) { return function(_args) { // One parameter, what about multiple parameters? return _obj[_method](_args) } } ['foo', 'bar', 'baz'].forEach(function(method) { delegate[method] = delegate_to(method, that) }) delegate.foo('Hello JS') // foo: Hello JS delegate.bar('Hello JS') // bar: Hello JS delegate.baz('Hello JS') // baz: Hello JS 

The code really works, but what if I want to delegate a method that has several parameters? What about the parameters n ? Can I change the code to any number of parameters? Does it work in any browser?

Regards, Rainer

+4
source share
2 answers

The function has methods called "apply" to pass a variable number of parameters as an array. See MDC: Function.apply

You can convert all parameters passed to a function to an array using Array.prototype.slice.call(arguments, 0)

Using these two principals, I changed your code to several parameters. See JSBin http://jsbin.com/iwiwix/3/watch

Corresponding code extract:

 delegate.foo('Hello JS', "from foo"); // foo: Hello JS function delegate_to(_method, _obj) { return function() { var argArray = Array.prototype.slice.call(arguments, 0); return _obj[_method].apply(_obj, argArray); }; } that.foo = function() { console.log("foo: " + arguments[0] + ' ' + arguments[1]); }; 
+1
source

Try the following:

 function delegate_to(_method, _obj) { return function() { return _obj[_method].apply(_obj, [].slice.call(arguments)) } } 
+2
source

All Articles