In the early stages of its development JavaScript was not as flexible and complex a language as it is now. There were some functions indispensable for that time but not that important nowadays. One of them is eval()
.
This function can accept a string as a parameter, consider it as a code and then execute it. The syntax is very easy and is shown in the following example.
eval("console.log('Test string')");
// logs "Test string"
Note that the string argument is not obligatory. You can execute this function without any parameters at all. However, in this case it will return an undefined value.
console.log(eval());
// logs "undefined"
You can write more than one command in the string that will be passed. Along with simple logs eval()
can recognize and execute even some mathematical expressions. For example, the code below shows how to create and initialize variables, calculate their product and show the result in the console using the eval()
function.
eval("a = 5; b = -3.5; console.log(a*b)");
// logs "-17.5"
Although this function works with strings, you can as well pass a value of a different data type. In this case it will not perform any actions and will just return the same value.
Proper use of eval()
While using eval()
functions you need to pay attention to its access to global and local variables. In the following code there is a global variable num created and initialized with the value 5 and a local variable initialized with the value 3. The method is executed in its current context, so 3 will be printed in the output.
let num = 5;
function test()
{
let num = 3;
eval("console.log(num)"); // logs "3"
}
eval("test()");
Variables created inside eval()
are not visible outside. For example, the following code will bring you to an error message.
eval("let num1 = 7");
console.log(num1);
You need to be careful with the use of curly brackets and eval()
. The thing is that in JS not only objects are surrounded by brackets, but also blocks of code. The interpreter usually defines it by context.
The following command will bring you to the Syntax Error saying that “:
” is an unexpected token because eval()
considers it as a block instead of an object.
person = eval('{ "name": "John", "age": 30 }');
//Use parentheses to specify your object inside eval() and make it work properly.
person = eval('({ "name": "John", "age": 30 })');
console.log( person.age ); // logs "30"
Drawbacks
Nowadays eval()
is used extremely rarely. The reason, first of all, is its insecurity. The code passed to this function runs with the execution privileges. Therefore, there is always a danger of running a malicious code on a user’s computer. Plus, since eval()
has access to the global scope, it can also lead to possible attacks.
Another drawback of using eval()
is productivity. This function is much slower than its alternatives because it requires the JavaScript interpreter to be run while many other constructions are optimized by modern engines.
Modern JavaScript code compressors try to rename local variables automatically to make them look shorter. It’s safe since any local variable is visible only inside its function and if you change its name from “my_string” to “s”, it will be hard to notice.
However, if there is eval() in your code, compressors will probably avoid any changes of the variables in that block because there always will be a risk of using them with this unstable function. Thus, the quality of your code compression will be reduced.
Alternatives
Luckily, there is a good alternative to eval()
and that window.Function()
. That is a constructor which creates a function. It accepts two string arguments: the first one is a string of parameters that the created function will have and the second one is the body of your function. For example, in the following code a function to print the argument ‘a’ is created.
f = new Function('a', 'console.log(a)');
f(5);
The use of Function()
is much faster than eval(), plus it’s possible to execute it multiple times.
If you get information from an external server, you cannot be sure it’s safe. That’s why in case you need to process a string containing some data, it’s much better to use the JSON.parse()
method instead of eval()
. If JSON.parse()
finds something incorrect in the received string, you will just get an error message while eval()
will actually try to execute the code and in that way will put you in danger.
The example below illustrates how easy it is to use the JSON.parse()
method. This function received a string of characters as a parameter and simply converted it into an actual object, so it became possible to access the object’s properties.
var a = '{"name": "John", "age": 30}';
b = JSON.parse(a);
console.log(b['name']); // logs "John"
console.log(b['age']); // logs "30"
Summary
Sometimes the programmers face situations when they need to execute a command which is yet unknown. That is when they want to perform a command received as a string parameter. For example, while creating a dynamic calculator where a user enters an expression and the program gives the result.
JavaScript offers a special function for such cases - eval()
. However, using it is not recommended because of various safety risks and low productivity. There are some good alternatives to use instead of eval()
. For example, Funtion()
constructor or JSON.parse()
method.