ObiHill
ObiHill

Reputation: 11886

Javascript Dynamic Function Call with Name

So I have the following pseudo Javascript code:

var Class = (function(window, document, $) {
    function meth_1()
    {
        //some code
    }

    function meth_2()
    {
        //some code
    }

    function meth_3()
    {
        //some code
    }

    function meth_4()
    {
        //some code to call other three functions dynamically
    }

    Class = {
        meth_1: meth_1,
        meth_2: meth_2,
        meth_3: meth_3,
        meth_4: meth_4
    };
    return Class;

})(window, document, jQuery);

In the meth_4 function, I want to call the other 3 functions dynamically by passing the function name as a string. How can I do this?!

In this related StackOverflow question, the answer provides a solution to how this could be done in window scope i.e. window[function_name](). However, I'd like to know how I can do it in my particular circumstance.

Thanks.

EDIT

The answer I selected works ok. You could also do the following:

var Class = (function(window, document, $) {
    var meth_func = {
        meth_1: function(){/**your code**/},
        meth_2: function(){/**your code**/},
        meth_3: function(){/**your code**/}            
    }

    function meth_4(func_name)
    {
        meth_func[func_name]();
    }

    Class = {
        meth_4: meth_4
    };
    return Class;

})(window, document, jQuery);

This would probably work better if you wanted to make private those three functions being called dynamically.

Upvotes: 3

Views: 12440

Answers (3)

Rune FS
Rune FS

Reputation: 21752

Here's an implementation that can do what you want. If you pass a string it will simply look up the appropriate function and execute it. However since functions in JS are indeeed objects them self you can pass those around and to show that I've extended the functionality a bit compared to what you ask for. If you pass a function (actual anything but a string) it will (try to) invoke it

meth_4 = function(fun){
   if(typeof fun === 'string'){
       this[fun](args.slice(1));
   } else { //assuming it's a function
       if(arguments.length == 1)
          fun.call(this,[])
       } else {
          fun.apply(this,arguments.slice(1))  
       }
   }
}

JavaScript objects are, or at can be treated as, a key/value pair collection. Any function or property can be access in two semantically equivalent ways

obj.key or obj["key"] in certain cases only the latter can be used. E.g. if the property is called property nameyou can't do obj.property name but can do obj["property name"]

Upvotes: 0

strandel
strandel

Reputation: 21

I don't know why you would want that (also 'Class' is not good as a variable name), but could be done like this:

var Class = (function (window /*, ... */) {
  return {
    func1: function () {console.log('1')}
  , func2: function () {console.log('2')}
  , func3: function () {console.log('3')}
  , func4: function (funcName) {
      console.log('4+')
      this[funcName]()
    }
  }
})(window)

Class.func4('func3')

Upvotes: 0

Frédéric Hamidi
Frédéric Hamidi

Reputation: 263047

Since you want to call functions using bracket notation in object scope, not window scope, you can use this instead of window:

function meth_4()
{
    this["meth_1"]();
    this["meth_2"]();
    this["meth_3"]();
}

Upvotes: 2

Related Questions