簡體   English   中英

當我將其名稱作為字符串時,如何執行私有JavaScript函數

[英]How to execute a private JavaScript function when I have its name as a string

我正在嘗試從返回的對象中執行私有函數。 如果我提前知道函數的名稱,這很容易,但在這種情況下,我不知道有哪些函數可用。 我所擁有的是一個字符串,其中包含要調用的函數的名稱。 有沒有辦法通過字符串調用這些函數?

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函數的最佳方法是什么? 謝謝你的幫助。

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

 foo[functionName](); 

是的,那是試圖訪問foo函數的[public]屬性。 例如,它可以使用"call"方法。

這有效,但我試圖避免評估。 我不確定這不是那么糟糕

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

這有效。 我不確定這是否比funcRunner2更差或相同;

 eval(functionName + "()"); 

eval的角度來看,兩者都和另一個一樣糟糕。 選項1確實使得更容易使用參數[不需要動態評估]。

這可以工作,但需要exec對象,如果可能的話我想避免。

 exec[functionName](); 

這只是做到這一點的方式。 由於execfoo范圍內的局部變量,因此您甚至可以擁有自己的私有性。 看來你也已經為publicObj切換了exec

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

publicObj變量盡管名稱不公開,但它是用var關鍵字聲明的本地變量! 順便說一下,你可以把它簡化為

var exec = {
    test: bar
};

為什么不創建一個私有命名空間(對象)並使用它而不是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

它有點類似於你的“不理想”解決方案,但有點不同。 如果將所有函數組織到對象中,則可以調用它們。 在調用原始函數的對象中不需要其他函數。

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");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM