14

I have the following script:

(function () {
    var Module = (function () {
        var fctToCall = function () {
            alert('Foo');
        };
        return {
            fctToCall: fctToCall
        };
    })();
    var Module2 = (function () {
        var init = function () {
            var str = 'fctToCall';
            Module.str(); // here
        };
        return {
            init: init
        };
    })();
})();

So I want to call this fctToCall method by its name - how can I do that? So far I know 3 methods:

  • by attaching the function to the window object, but then it wouldn't be local and in closure, and I wouldn't have the access to other local variables
  • eval, the best options as far as I see it, but it's still eval, so I don't wanna use it
  • this, but it's another architecture, I don't wanna change it

How can I solve this?

Tushar
  • 85,780
  • 21
  • 159
  • 179
user99999
  • 1,994
  • 5
  • 24
  • 45

4 Answers4

17

To call function use

Module[str]();

As Module is an object, you can access the dynamic properties and methods of it by using the bracket notation.

(function() {
  var Module = (function() {
    var fctToCall = function() {
      console.log('Foo');
    };
    return {
      fctToCall: fctToCall
    };
  })();
  var Module2 = (function() {
    var init = function() {
      var str = 'fctToCall';
      
      // Call as
      Module[str]();
    };
    return {
      init: init
    };
  })();

  Module2.init();
})();
Tushar
  • 85,780
  • 21
  • 159
  • 179
7

Replace:

var init = function () {
    var str = 'fctToCall';
    Module.str(); // here
};

With:

var init = function () {
    var str = 'fctToCall';
    Module[str](); // here
};

Here, str is used as key to access the fctToCall function on Module.

Then you can call Module2.init(), in your IIFE:

(function() {
  var Module = (function() {
    var fctToCall = function() {
      document.write('Foo'); // (alert is broken in snippets)
    };
    return {
      fctToCall: fctToCall
    };
  })();
  var Module2 = (function() {
    var init = function() {
      var str = 'fctToCall';
      Module[str](); // Access & call `fctToCall`.
    };
    return {
      init: init
    };
  })();
  Module2.init(); // Call `init`.
})();
Cerbrus
  • 70,800
  • 18
  • 132
  • 147
1

Since everything in JS is object you can use the object notation.

Module[str]();
Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
1

You can just invoke the function like this:

Module[str]();
ogugger
  • 122
  • 6