调用名称存储在变量中的函数

use*_*999 12 javascript

我有以下脚本:

(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
        };
    })();
})();
Run Code Online (Sandbox Code Playgroud)

所以我想fctToCall通过它的名字来调用这个方法 - 我该怎么做?到目前为止,我知道3种方法:

  • 通过将函数附加到窗口对象,但它不会是本地和闭包,我将无法访问其他局部变量
  • eval,就我看来最好的选择,但它仍然是eval,所以我不想使用它
  • 这,但它是另一种架构,我不想改变它

我怎么解决这个问题?

Tus*_*har 15

调用功能使用

Module[str]();
Run Code Online (Sandbox Code Playgroud)

作为Module对象,您可以使用括号表示法访问它的动态属性和方法.

(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();
})();
Run Code Online (Sandbox Code Playgroud)

  • `Module`不是一个函数.这是一个对象.具体来说:`{fctToCall:fctToCall}` (2认同)

Cer*_*rus 6

更换:

var init = function () {
    var str = 'fctToCall';
    Module.str(); // here
};
Run Code Online (Sandbox Code Playgroud)

附:

var init = function () {
    var str = 'fctToCall';
    Module[str](); // here
};
Run Code Online (Sandbox Code Playgroud)

这里,str用作访问fctToCall函数的键Module.

然后你可以Module2.init()在你的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`.
})();
Run Code Online (Sandbox Code Playgroud)