2

I have an object with a set of prototype methods. How do I invoke that method given is name and arg list?

So I have and object:

scarpa.MyThing = function() {
}

MyThing has a prototype method:

scarpa.MyThing.prototype.beAwesome = function(a, b, c) {
    // do awesome stuff here with a, b, and c
}

Now, I want to call beAwesome from another prototype method:

scarpa.MyThing.prototype.genericCaller = function(methodName, d, e, f) {

    // this does not work for me
    this.call(methodName, d, e, f)

}

Here is the call to genericCaller:

this.genericCaller('beAwesome', alpha, zeta, bravo);

I am stuck on the proper syntax for the call within genericCaller.

Can someone please enlighten me? Thanks.

dugla
  • 12,774
  • 26
  • 88
  • 136

3 Answers3

5

You want to use bracket notation and apply

scarpa.MyThing.prototype.genericCaller = function(methodName) {
    var args = [].slice.call(arguments);  //converts arguments to an array
    args.shift(); //remove the method name
    this[methodName].apply(this, args);  //call your method with the current scope and pass the arguments
};

Nice thing with using arguments is you do not have to worry about the d, e, f all the time. You can pass in 20 things and it will still work.

epascarello
  • 204,599
  • 20
  • 195
  • 236
  • 1
    I like this one the most because it's variadic. edit- just saw your edit saying the same thing. – Antiga Dec 07 '15 at 15:51
  • 1
    @Antiga After I posted and saw 2 other answers using .call, I thought I should point out why this is a little better. :) Than I saw your comment after the edit. lol – epascarello Dec 07 '15 at 15:54
  • Yep. Nifty. JS is like the gumby language. Coolness. Cheers. – dugla Dec 07 '15 at 21:42
  • 1
    There is actually a bug in your code snippet. I use args.shift() instead of args.pop(). Shift clobbers the method name. Pop clobbers the last arg in the arg list. Minor nit. – dugla Dec 08 '15 at 14:44
  • 1
    Must have been the lack of coffee... :) – epascarello Dec 08 '15 at 14:45
  • No worries. This is actually a huge help in my ability to fully grok JS which I am warming to. Cheers. – dugla Dec 08 '15 at 14:47
0

There were quite a few errors in that code. Try this.

'call' is a function which is available to Functions. You were trying to invoke it on an object(this). That wont work.

All you have to do is do this[methodName].call(). Call takes context as the first argument, so pass this. And then the remaining arguments.

var scarpa = {};
scarpa.MyThing = function() {
}

scarpa.MyThing.prototype.beAwesome = function(a, b, c) {
    // do awesome stuff here with a, b, and c
    console.log(arguments);
}

scarpa.MyThing.prototype.genericCaller = function(methodName, d, e, f) {


    //this[methodName].call(this,d,e,f)
    this[methodName](d, e, f)

}

var m = new scarpa.MyThing();
m.genericCaller('beAwesome', "", "", "");
Bhargav Ponnapalli
  • 9,224
  • 7
  • 36
  • 45
0

Have you tried doing it like this?

scarpa.MyThing.prototype.genericCaller = function(methodName, d, e, f) {
    this[methodName](d, e, f);
}

This works because scarpa.MyThing is also an object, which elements you may get by dot or []

vessel
  • 56
  • 4