eval() argument written as Javascript code in IDE

on

MDN web docs clearly state you should never use eval() in Javascript. However, sometimes you might need it and sometimes you might want it. But it is a pain to use, as you have to provide it Javascript as a string between literals. And if you want to pass a larger chunk, that becomes clumsy.

So, if you really want to use eval() in Javascript (and, as it was mentioned before, you should never do this!), and want to write the argument in clean Javascript using code validators, Intellisense, code formatting and what not, check this out.

TL; DR;

Check out this code:

var functionContentString = (function () {
  console.log('This is an example of a JS function!');
  console.log('You could write any code here!');
})
  .toString()
  .match(/{(.|\s)*}/)?.[0]?
  .slice(1, -1)?
  .trim();

eval(functionContentString);

The dummy function with two console.log lines is first transferred to a string using the .toString() method. Next, a regex is applied that finds the opening and closing curly braces and returns everything inside. Note it is set to be greedy so it only finds the first and last curly braces and gets what is inside them – the body of the function. The slice() method then removes the curly braces and .trim() is there to trim the extra white spaces to the side.

After applying all this to the function provided, inside the functionContentString only

console.log('This is an example of a JS function!');
console.log('You could write any code here!');

remains, and this is executed via the eval() function.

Problem

If you need to write a large or a more complex piece of code that you want to execute using an eval() statement (and you should never use eval() statements to execute code!), then it is clumsy and you end up doing something like this:

eval(
  'console.log(\'This is my first command.\');' +
  'console.log(\'This is my second command.\');'
);

Main problems here are:

  • You cannot use the advantages modern IDEs provide you with like syntax checking, automated formatting, code coloring, Intellisense etc.
  • You constantly need to pay attention to escaping everything you need to escape in order for the string to come out exactly the way you want it.

I would love to use all the benefits that the IDE provides me with, as well as not think about (or learn) the whole list of characters that need to be escaped inside quotes.

.toString() method on a function returns code

In Javascript, if you use the .toString() method on an object, you will get [object Object]. However, if you use it on a function, you will get the whole code of the body. Try running:

(function () {
  console.log('This is my function');
}).toString();

It will actually output the code.

So, what you could do to solve the mentioned problem is to make a function that you would not use in your code. This will allow you to write it in Javascript (not under quote marks) in your IDE using all the benefits it has to bring.

After you do that, it is only a matter of turning it into a string, getting rid of everything that is not the function body and passing it on to the eval() statement. Did I mention you should never use eval()?

How we do this is explained in the TL;DR; part.

Conclusion

You should never use eval().

If you end up using eval(), there is a way to write code in Javascript in your IDE and then just pass that code to the function. Which makes life easier in those rare cases you do end up using eval(). Thanks to ofzza for showing me this neat little trick!

Leave a Reply

Your email address will not be published. Required fields are marked *

You are currently offline