In order to set up a Socket.IO client, I have a bunch of methods looking like this:
myobject.prototype.A = function (callback) {
this.foo('a', null, callback);
}
myobject.prototype.B = function (bar, callback) {
this.foo('b', { bar }, callback);
}
myobject.prototype.C = function (baz, qux, callback) {
this.foo('c', { baz, qux }, callback);
}
The content of this.foo
is unimportant, but it takes 3 parameters: a string, an object built from the calling method parameters, and a callback method.
I’d like to have the methods set up in a single place. I’d like to have something looking like this:
// I'm not sure what form the args should take
const methods = {
A: { socketName: 'a', args: [ ] },
B: { socketName: 'b', args: [ 'bar' ] },
C: { socketName: 'c', args: [ 'baz', 'qux' ] }
};
for (let m in methods) {
const mData = methods[m];
this.prototype[m] = function (what_do_I_put_here_?, callback) {
// how do I form "otherArgs" ?
this.foo(mData.socketName, otherArgs, callback);
}
}
I think I’ll have to look to destructuring assignments but I’m not sure how to use them in this case.
2
Answers
You could do that utilizing closures and an array function:
If you really need it as member functions you could do:
If it is only about member functions you could get rid of the the arrow function like this:
As I don’t know the exact use case, it is hard to come up with a solution that exactly matches the needs. But based on the shown code, you should get an idea how this can be achieved.
This utilises a higher order function that can wrap/decorate functions and enforce the needed parameters.
Function.call
would also set the value ofthis
when calling, thus if decorating a method it will use the value ofthis
where it is called from as usual:There is the
toObj
which should take the keys and varargs, then produce an object out of them. I use a ready made implementation for brevity –_.zipObject()
from Lodash. However, it can be custom changed or entirely custom built, if needed.With that a call would look like
which will produce a function that can be called like
which would in turn call
Two notable things:
length
property of the wrapped function will report zero, as that is how the rest syntax for parameters is defined to work. This means that examining it to find the number of parameters before calling will be unreliable