Let's Try To Call A Function By A String In JavaScript
MkDay
Posted on November 8, 2021
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;
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
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
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
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
}
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
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
It works as follows.
operations[currentOperation](8, 2); // returns 10
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
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
Posted on November 8, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
October 25, 2024
October 6, 2024