DEV Community

Cover image for Let's Try To Call A Function By A String In JavaScript
MkDay
MkDay

Posted on

Let's Try To Call A Function By A String In JavaScript

If you know the basics of JavaScript, then you know how to call a Function. However, what if we want to call a function differently?

FUNCTION NAME AS A STRING

Here is the real-world use case that I have tried.

There is a set of functions and, there is also a set of string variables with values ​​corresponding to each function name.

The user also can select the corresponding string variable that has a value equal to the name of the function he intends to execute at this moment.


// set of functions

 function add(num1, num2) {
 console.log(num1 + num2);
}

function subtract(num1, num2) {
 console.log(num1 - num2);
}

function divide(num1, num2) {
 console.log(num1 / num2);
}

function multiply(num1, num2) {
 console.log(num1 * num2);
}

// set of string variables

let operationAdd = 'add';
let operationSubtract = 'subtract';
let operationDivide = 'divide';
let operationMultiply = 'multiply';

// user input

let currentOperation = operationAdd;

Enter fullscreen mode Exit fullscreen mode

Now if we call the function add() {} using the variable currentOperation which currently has the value add, it will give us an error.


currentOperation(8, 2); // throws an error

Enter fullscreen mode Exit fullscreen mode

It seems that we cannot replace a function name directly with a string. However, I found some great ways to do it.

WAYS TO REPLACE A FUNCTION NAME WITH A STRING

1. Using eval()

The eval() function evaluates JavaScript code represents as a string. That string can be a JavaScript expression, a statement, or a sequence of statements. The expression can include variables and properties of existing objects.

In the code below, we concatenate the string value of the function name with the arguments in parentheses as a single string and pass it to the function eval() as its argument.


function add(num1, num2) {
  console.log(num1 + num2);
}

let currentOperation = 'add';

let functionString = currentOperation + '(8, 2)';

eval(functionString); // returns 10

Enter fullscreen mode Exit fullscreen mode

However, the eval() function is not a good solution for that. Why because it has significant drawbacks. More importantly, it is insecure and slows down the code running. You can learn more about why you should not use eval() here.

2. Using Function Object

We can use the Function object as an alternative to the eval() function. Here we create an instance of the Function and pass our function in string format as its argument as we did before with eval().


function add(num1, num2) {
 console.log(num1 + num2);
}

let currentOperation = 'add';

let functionString = currentOperation + '(8, 2)';

let newFunction = new Function(functionString);

// function call
newFunction(); // returns 10

Enter fullscreen mode Exit fullscreen mode

3. Using Function.name

The name property of the Function object returns name of the function as a string.

Using the .name property, we can compare a function name as a string value with another string. Then we can call the function as usual.


function add(num1, num2) {
 console.log(num1 + num2);
}

let currentOperation = 'add';

if(currentOperation === add.name) {
 add(8, 2); // returns 10
}

Enter fullscreen mode Exit fullscreen mode

4. Using window Object

Since all the items, such as variables and functions in JavaScript, are properties (or methods) of the window object, we can call a function as a method of the window object.


function add(num1, num2) {
 console.log(num1 + num2);
}

let currentOperation = 'add';

window[currentOperation](8, 2); // returns 10

Enter fullscreen mode Exit fullscreen mode

This method works well with global functions. However, it may not work for some cases such as namespaced-functions.

See the example below.

let operations = {
  add: function(num1, num2) {
    console.log(num1 + num2);
  },

  subtract: function(num1, num2) {
    console.log(num1 - num2);
  }
};

let currentOperation = 'add';

// The following code will not work
// window[operations.currentOperation](8, 2); // throws an error

Enter fullscreen mode Exit fullscreen mode

It works as follows.


operations[currentOperation](8, 2); // returns 10

Enter fullscreen mode Exit fullscreen mode

5. Using a custom function (Recommended)

Also, we can create a custom function to call a function using its name as a string. It is more flexible and accurate than the others.


function add(num1, num2) {
 console.log(num1 + num2);
}

let currentOperation = 'add';

function executeFunctionByName(functionName, context /*, arg*/) { 
let args = Array.prototype.slice.call(arguments, 2); 

let namespaces = functionName.split("."); 

let func = namespaces.pop(); 

  for(let i = 0; i < namespaces.length; i++) { 

    context = context[namespaces[i]]; 
  } 

return context[func].apply(context, args); 

}

executeFunctionByName(currentOperation, window, 8, 2); // returns 10

Enter fullscreen mode Exit fullscreen mode

THE BEST WAY AND THE WORST WAY

In my opinion, it depends on your requirement when choosing the best way to do the job. However, it is a good practice not to use eval() for this purpose. Considering all the methods discussed above, I think the last one is the most efficient way to do it.

If you have tried these methods or any other methods, please let us know your experience with them. Because always we love to learn from each other.

Image credit: Shahadat Rahman on Unsplash

Discussion (0)