2

I have about 7 string names that I would like to use inside if/else to echo a function like:

function main (str) {
 if(str == "a"){
   a()
 }

 if(str == "b"){
  b ()
 }
}

My question is, is there anyway to just call function directly using the str value? without using if/else of course

kboul
  • 13,836
  • 5
  • 42
  • 53
hidar
  • 5,449
  • 15
  • 46
  • 70

5 Answers5

1

You could use an object with references to the functions, like

var fn = {
        a: a,
        b: b
    };

Call with

fn[str]();
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

use eval : https://www.w3schools.com/jsref/jsref_eval.asp

function a(){
  console.log('hello a');
}
    
function b(){
  console.log('hello b');
}
    
function main(str){
  eval(str)();
}
    
main("a");

more examples and details : Evaluating JavaScript code via eval()

and eval isnt evil just misunderstood

keep in mind that eval isn't the best solution for every case, a quote from a comment in the article above :

From a security perspective, eval() is far more dangerous in a server environment, where code is expected to be fully trusted and hidden from the end user.

In a browser, the user could eval any code they wanted at any time simply by opening dev tools, so as a developer you can't get away with having anything on your client code that could be insecure against eval anyway.

Taki
  • 17,320
  • 4
  • 26
  • 47
  • You share a good article. Also I looked into the comments of that article, then found some comments (especially from Spudley) are interesting. – Sphinx Mar 30 '18 at 18:40
  • thank you :) the goal is to share as much information as we can and it's up to the OP to use whatever he finds fit for his case. – Taki Mar 30 '18 at 18:44
1

Construct one object to save all functions with their names, then call like list[name]().

eval() (like eval('the name of your function')) may be another solution, but it will be dangerous and may be slower.

Like MDN said:

eval() is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, a third-party code can see the scope in which eval() was invoked, which can lead to possible attacks in ways to which the similar Function is not susceptible.

eval() is also slower than the alternatives, since it has to invoke the JS interpreter, while many other constructs are optimized by modern JS engines.

var functionList = {'a':function(){console.log('a')}, 'b':function(){console.log('b')}}


function main (str) {
  functionList[str]()
}

main('a')
main('b')
Sphinx
  • 10,519
  • 2
  • 27
  • 45
  • eval isn't evil, it's just misunderstood, and the goal here is to answer the OP's question, not discouraging other answers nor copy / pasting the first answer ;) , if you find an answer like yours, upvote it instead of editing it and posting another. – Taki Mar 30 '18 at 18:27
  • =. =, I have to state I didn't downvote yours... then my answer was still editing when first answer posted, and I keep this answer because I just want to explain something more on this question. – Sphinx Mar 30 '18 at 18:35
  • i never said you downvoted mine, as i was pointing to a different possibility regardless of it's drawbacks, – Taki Mar 30 '18 at 18:39
  • Yes, I agree. Any solutions should be appreciated even some of the solutions may have potential performance issue or else. The key point is help us open our mind in SO. – Sphinx Mar 30 '18 at 18:44
1

You could assign all your functions to an object and then use the Bracket notation

Like in this snippet:

let a = () => console.log('a'),
    b = () => console.log('b');

let functions = { a, b }

functions['a']()

Now depending if you are running in the browser or in node, you could use the window(browser) or global(node) object, that also holds your function and thus could avoid the need of the functions object like above

So you could do (here for example in node) something like:

global['a']()
Renato Gama
  • 16,431
  • 12
  • 58
  • 92
Kristianmitk
  • 4,528
  • 5
  • 26
  • 46
1

Using method name in string is NOT recommended, as names of functions are changed when you create a minified production build. Which results in getting a broken build.

Although, it can be done by following ways,

const methods = {
  'a': () => {
    // code for method "a"
  },
  'b': () => {
    // code for method "b"
  }
  ...
};

const main = (methodName) => {
  methods[methodName]();
};