Introduction
In this article, we’ll learn to create dynamic functions from strings on the fly.
Functions 101
A function is the fundamental building block in JavaScript. A function consists of a group of statements that perform a specific task. A function could accept input in the form of parameters and produce output using the return statement.
Creating a function is quite straightforward. Primarily, there are two ways to create a function.
Function Declaration
function square(num) {
return num * num;
}
As you can see in the above example square function accepts a single parameter called num and returns the square of that number
Function Expression
The above function declaration can be represented in the form of expression as follows.
const square = function(num) {
return num * num;
}
You could also use an arrow function to create a function expression.
const square = function(num) {
return num * num;
}
One thing we need to take into account is every function created in JavaScript is an instance of the Function object.
function square(num) {
return num * num;
}
console.log(square instanceof Function)
// output: true
const square = function(num) {
return num * num;
}
console.log(square instanceof Function)
// output: true
const square = function(num) {
return num * num;
}
console.log(square instanceof Function)
// output: true
Creating The Dynamic Function
Syntax
The Function object can also be used as a constructor function to create a new function on the fly. The syntax for creating a function from a Function Object is as follows.
const myFunction = new Function(arg1, arg2, …argN, body);
args1, args2,.. args are the arguments accepted by the function and the body is the string consisting of JavaScript statements that will be executed when the function is called.
Examples
Let’s quickly understand this in detail with the help of an example.
const sq = new Function('num', 'return num * num');
sq(2); // output: 4
In the above code snippet, we’re creating a function that accepts a single parameter ‘num’ and returns the square of that number.
Let’s take a look at one more example. The following function accepts two parameters x and y and returns the result of the multiplication of those two numbers.
const multiply = new Function('x', 'y', 'return x * y');
multiply(2, 5); // output: 10
It’s also possible to create a function that doesn’t accept any parameters.
const logger = new Function('console.log("hello javascript")');
logger(); // output: hello javascript
You could also write function body on multiple lines using es6 template literals.
const square = new Function('numbers', `
return numbers
.map(num => num * num)
`);
One thing to keep in mind is the functions created with new Function syntax are created in the global scope and will not be able to access the current lexical environment.
Hence, the function won’t be able to access variables from its outer lexical environment.
function myFunc() {
const num = 2;
const sq = new Function('return num * num');
return sq;
}
myFunc()();
// output: Uncaught ReferenceError: num is not defined
However, function declarations do have access to its outer environment.
function myFunc() {
const num = 2;
const sq = function() { return num * num };
return sq;
}
myFunc()(); // output: 4
This feature is rarely needed but could be unavoidable in certain situations. Imagine you’re building complex web-based applications and have stored logic in the form of code on the server-side environment and wish to generate functions using that logic on the go.
One thing to note is apart from these rare situations creating dynamic functions should be avoided as they make the code prone to security and performance issues.
Summary
TLDR, The Function object could be used as a constructor function to create dynamic functions on the fly.
Syntax
const myFunction = new Function(arg1, arg2, …argN, body);
Examples
const sq = new Function('num', 'return num * num');
sq(4); // Output: 16