当我将其名称作为字符串时,如何执行私有JavaScript函数

时间:2013-12-21 19:33:28

标签: javascript private

我正在尝试从返回的对象中执行私有函数。如果我提前知道函数的名称,这很容易,但在这种情况下,我不知道有哪些函数可用。我所拥有的是一个字符串,其中包含要调用的函数的名称。有没有办法通过字符串调用这些函数?

function foo() {

  // some misc. chunk of valid javascipt code
  function bar() {
      console.log("hello");
  }
  // end misc. code

  // I would like to avoid doing this if I don't have to
  var executableFn = {};
  executableFn.test = function() {
    bar();
  }
  // end

  return {
    // This works but requires I know the name of the funciton ahead of time.
    // All I have is a string name of the function to call.
    funcRunner0: function() {
      bar();
    }, 
    // My ideal method for calling but does not work
    funcRunner1: function(functionName) {
      foo[functionName]();
    }, 
    // This works but I'm trying to avoid eval.  I'm not sure if this is not so bad
    funcRunner2: function(functionName) {
      var func = eval(functionName);
      func();
    },
    // This works.  I'm not sure if this is worse than funcRunner2 or the same;
    funcRunner3: function(functionName) {
      eval(functionName + "()");
    },
    // This works but requires the executableFn object which I would like to avoid if at all possible.
    funcRunner4: function(functionName) {
      executableFn[functionName]();
    }, 
  };
}

var bas = foo();

// This works but assumes I know the name of the function to call which I don't. 
bas.funcRunner0();
// This doesn't work
bas.funcRunner1("bar");
// This works
bas.funcRunner2("bar");
// This works
bas.funcRunner3("bar");
// This works but is not my ideal
bas.funcRunner4("test");

这些是我用来调用此功能的所有方法。您认为用字符串调用bar函数的最佳方法是什么?谢谢你的帮助。

3 个答案:

答案 0 :(得分:2)

  

我理想的呼叫方法但不起作用

foo[functionName]();

是的,那是试图访问foo函数的[public]属性。例如,它可以使用"call"方法。

  

这有效,但我试图避免使用eval。我不确定这是不是很糟糕

var func = eval(functionName);
func();
     

这很有效。我不确定这是否比funcRunner2更差或相同;

eval(functionName + "()");

eval的角度来看,两者都和另一个一样糟糕。选项1确实使得更容易使用参数[无需动态评估]。

  

这有效但需要exec对象,如果可能的话我想避免。

exec[functionName]();

这就是做到这一点的方法。由于execfoo范围内的局部变量,因此您甚至拥有自己的私有性。您似乎已将[{1}}切换为exec

publicObj

// I would like to avoid doing this if I don't have to var publicObj = {}; publicObj.test = function() { bar(); } 变量尽管名称不公开,但它已使用publicObj关键字声明为本地变量!顺便说一下,你可以把它简化为

var

答案 1 :(得分:1)

为什么不创建一个私有命名空间(对象)并使用它而不是exec / eval?

function foo() {

    var private_ns = {
        bar : function() {
            console.log('bar', arguments);
        }
    };

    return {
        call_func: function(name) {
            if(name in private_ns) {
                var args = [].slice.call(arguments, 1)
                return private_ns[name].apply(null, args);
            } else {
                console.error('no such function');
            }
        }
    };
}

var f = foo();

> f.call_func('bar', 1, 2, 3);
bar { '0': 1, '1': 2, '2': 3 }

> f.call_func('noop');
no such function

答案 2 :(得分:0)

它有点类似于你的“不理想”解决方案,但有点不同。如果将所有函数组织到对象中,则可以调用它们。在调用原始函数的对象中不需要其他函数。

http://jsfiddle.net/L3n4Z/

function foo() {

    // all functions stored in this object
    var functions = {
        bar : function() {
          console.log("hello");
        }
    };

  return {
    funcRunner: function(funcName) {
      functions[funcName]();
    }
  };
}

var bas = foo();
bas.funcRunner("bar");