Eval is evil, part one

The eval method
— which takes a string containing JScript code, compiles it and runs it — is probably
the most powerful and most misused method in JScript. There are a few scenarios in
which eval is
invaluable. For example, when you are
building up complex mathematical expressions based on user input, or when you are
serializing object state to a string so that it can be stored or transmitted, and
reconstituted later.


these worthy scenarios make up a tiny percentage of the actual usage of eval. In
the majority of cases, eval is
used like a sledgehammer swatting a fly — it gets the job done, but with too much
power. It’s slow, it’s unwieldy, and
tends to magnify the damage when you make a mistake. Please
spread the word far and wide: if you are considering
eval then
there is probably a better way.
hard before you use eval.


me give you an example of a typical usage.





setspan(num, text)


+ num + “.innerText = ‘” + text + “‘”);



the program is getting its hands on a number, and it wants to map that to a particular
span. What’s wrong with this picture?


pretty much everything. This
is a horrid way to implement these simple semantics.
off, what if the text contains an apostrophe? Then
we’ll generate


= ‘it ain’t what you do, it’s the way thacha do it’;

isn’t legal JScript. Similarly, what
if it contains stuff interpretable as escape sequences? OK,
let’s fix that up.


+ num).innerText = text;

you have to use
eval, eval as
little of the expression as possible, and only do it once.
seen code like this in real live web sites:


if (eval(foo)
!= null && eval(foo).blah == 123)

= “hello”;


Yikes! That
calls the compiler three times to compile up the same code! People, eval starts
a compiler
. Before
you use it, ask yourself whether there is a better way to solve this problem than
starting up a compiler!


our modified solution is much better but still awful. What
if num is
out of range? What if it isn’t even a
number? We could put in checks, but why
bother? We need to take a step back here
and ask what problem we are trying to solve.


have a number. We would like to map that
number onto an object. How would you
solve this problem if you didn’t have eval? This
is not a difficult programming problem! Obviously
an array is a far better solution:


var spans
= new Array(null, myspan1, myspan2, myspan3);

setspan(num, text)


(spans[num] != null)

= text;



since JScript has string-indexed associative arrays, this generalizes to far more
than just numeric scenarios. Build
any map you want. JScript even provides
a convenient syntax for maps!


var spans
= { 1 : mySpan1, 2 : mySpan2, 12 : mySpan12 };


compare these two solutions on a number of axes:


what is easier to debug, a program that dynamically generates new code at runtime,
or a program with a static body of code? What
is easier to debug, a program that uses arrays as arrays, or a program that every
time it needs to map a number to an object it compiles up a small new program?


What’s easier to maintain, a table or a program that dynamically spits new code?


which do you think is faster, a program that dereferences an array, or a program that
starts a compiler?


which uses more memory, a program that dereferences an array, or a program that starts
a compiler and compiles a new chunk of code every time you need to access an array?


is absolutely no reason to use eval to
solve problems like mapping strings or numbers onto objects. Doing
so dramatically lowers the quality of the code on pretty much every imaginable axis.


gets even worse when you use eval on
the server, but that’s another post.



Tags JScript Performance Scripting

Comments (29)

Cancel reply

You must be logged in to post a comment.

  1. Dan Shappir says:If I were to rewrite the HTML I would implement it as:No eval and also no lookup table that must be kept in sync with the HTML.Speaking of “new Function”, eval’s sibling so to speak, here is an interesting if somewhat extreme example of its use:The local frames were generated using a custom OSP, feeding data directly into the HTML via binding. The user could filter this view by filling in a search form. The way filtering was done was that the OSP would generate an event, intercepted by a JavaScript event handler. If this handler returned false, the specific record was excluded.Fun times.
  2. Log in to Reply
  3. A big problem was performance – the view could contain hundreds, even thousands of records in extreme cases. Thus, it was imperative that the filtering would be as quick as possible. What I did was generate the JavaScript event handler on the fly based on the user’s input. This way I could construct optimal code for evaluating the specific filter expression.
  4. I was a lead developer for an application that was a mixed thin/fat client – some of the data was maintained locally, thus accessible while offline. The rest of the data was online. The way we did it was that the entire UI was DHTML + JavaScript, with some frames generated locally and the others provided by a web server.
  5. BTW, we do use eval a couple of time in the BeyondJS library, but BeyondJS is not you average JavaScript code. One example where we use it is to construct functions on the fly. The reason we use eval instead of “new Function” is because we need to create the function in the current scope.
  6. function setspan(num, text)
    var span = document.all(“myspan” + num);
    if (span != null)
    span.innertext = text;
  7. November 1, 2003 at 5:21 pm
  8. Bradley says:Another good way to get an element in the DOM is to use:
    document.getElementById(“myspan” + num);Log in to Reply
  9. Another benefit of this method (over eval or document.all) is that if you accidentally insert two (or more) elements with the same ID into the document, getElementById will always return an element (the first one), while eval (or document.all) will return a collection of all the elements with that ID, possibly causing code that expects a single element to fail.
  10. November 1, 2003 at 10:06 pm
  11. Dan Shappir says:getElementById has one significant advantage over document.all – it’s part of the DOM standard endorsed by the W3C, and is thus also supported by Mozilla. On the downside, it not supported by IE4 (not sure if anyone still cares about that version).Log in to Reply
  12. I’m not sure, however, that the fact that it returns the first element in the event of multiple existing elements with the same ID is an advantage. It means that if you accidentally create two elements with the same ID you might not notice and as result not fix the bug.
  13. November 2, 2003 at 4:21 am
  14. Meme Washer says:In the comp.lang.javascript Javascript Best Practices document; I came across an interesting discussion of the reasons for preferring square bracket notation to eval(). The consensus seems to be that eval is evil, and that &quot;if it exists in your page,..
  15. Log in to Reply
  16. June 6, 2006 at 8:35 am
  17. Mike’s Lookout » Blog Archive » Disection of a Spam Comment says:PingBack from http://www.belshe.com/2006/10/25/disection-of-a-spam-comment/
  18. Log in to Reply
  19. October 25, 2006 at 2:19 pm
  20. Steve says:Eval is easy… Hahahahahahah.Also:-Maintainability. Depends on the situtaion. Eval may be better.Memory. Aint a problem.Log in to Reply
  21. I think a lot of of “Gurus” are opposed to anything that makes life easier for us lesser beings.
  22. Speed. If it’s fast enough who cares.
  23. Debugability.   Well if bugs turn up I can always rewrite it the hard way. Also in many cases the eval code may be simpler and more readable.
  24. If  a fly is bugging me and I have a sledgehammer beside me, why go inside for and search for a flyswatter? That might take me half an hour.
  25. November 30, 2006 at 5:35 pm
  26. Alberto says:Steve Rocks!Though, going back to the eval thing, it is true that the eval is bad and that there is a number of workarounds (one of the reasons why i love js!).doing eval(‘obj.’ + methodName) seems a piece of cake. What about obj[methodName]() ? Much better.function ClassFactory(constructorClassName){    eval(‘myObj=new ‘ + constructorClassName +'()’)}Log in to Reply
  27. A class factory on the fly!!!
  28.     return myObj;
  29.     var myObj;
  30. Though there is nothing like:
  31. Workaround A: gotta call a method of an object but i know only the name.
  32. I agree, a religious conception of programming is the whorthest evil there is (bracket should be opened on a new line, etc);
  33. January 10, 2007 at 10:57 pm
  34. How to Use window.onload the Right Way says:PingBack from http://blog.roberthahn.ca/articles/2007/02/02/how-to-use-window-onload-the-right-way
  35. Log in to Reply
  36. February 2, 2007 at 10:01 am
  37. Why Won’t eval() Eval My JSON? (Or: JSON Object !== Object Literal) « The Curious Schemer says:PingBack from http://rayfd.wordpress.com/2007/03/28/why-wont-eval-eval-my-json-or-json-object-object-literal/
  38. Log in to Reply
  39. March 28, 2007 at 2:14 pm
  40. Template-Engine – Seite 3 – PHP @ tutorials.de: Forum, Tutorial, Anleitung, Schulung & Hilfe says:PingBack from http://www.tutorials.de/forum/php/268678-template-engine-3.html#post1415829
  41. Log in to Reply
  42. May 6, 2007 at 4:14 am
  43. Twey says:— QUOTE —function ClassFactory(constructorClassName){    eval(‘myObj=new ‘ + constructorClassName +'()’)}How about:function ClassFactory(constructorClassName) {}(Although the usefulness of this function is debatable, and the names misleading: there are no classes in JScript.)— CODE — eval(‘myobject.’ + propName + ‘ = ‘ “’ + propValue + ‘”’);// versus— END CODE —* I say “almost” — the example scenarios EricLippert gave are perfectly valid reasons to use eval(), and to write a dedicated JS parser for these situations is (usually) silly when eval() is already available.Log in to Reply
  44. P.S. Ugh, I had to switch browsers to post this — no Konq support on a blog that deals with web coding?
  45. Especially note, if we’re discussing getElementById() support, that some older browsers don’t support try/catch, so the only option when given a bad property name or value is to error out if you want to support these browsers.
  46. myobject.someProperty[propName] = propValue;
  47. } catch(e) {}
  48. try {
  49. Almost* everything that can be done with eval() can be done with square bracket notation, and not only is it more efficient, it’s also almost invariably simpler (you don’t have to worry about whether the input will form a valid JS expression, for a start) and produces neater code than eval():
  50. — END CODE —
  51.  return new this[constructorClassName]();
  52. — CODE —
  53. — END QUOTE —
  54.     return myObj;
  55.     var myObj;
  56. Though there is nothing like:
  57. August 14, 2007 at 4:03 am
  58. 5 Things I Hate About Ruby « Devi Web Development says:PingBack from http://deviweb.wordpress.com/2007/09/03/5-things-i-hate-about-ruby/
  59. Log in to Reply
  60. September 3, 2007 at 7:19 am
  61. The best Smarty + Zend View Helpers solution! | CodeUtopia says:PingBack from http://codeutopia.net/blog/2007/11/03/the-best-smarty-zend-view-helpers-solution/
  62. Log in to Reply
  63. November 6, 2007 at 12:52 am
  64. Ajax Girl » Blog Archive » Is using a JS packer a security threat? says:PingBack from http://www.ajaxgirl.com/2008/01/26/is-using-a-js-packer-a-security-threat/
  65. Log in to Reply
  66. January 26, 2008 at 4:32 am
  67. Javascript News » Blog Archive » Is using a JS packer a security threat? says:PingBack from http://www.javascriptnews.com/javascript/is-using-a-js-packer-a-security-threat.html
  68. Log in to Reply
  69. January 26, 2008 at 12:54 pm
  70. The Best Web Design Comics says:PingBack from http://blogsurfer.net/7270/the-best-web-design-comics-13.html
  71. Log in to Reply
  72. January 26, 2008 at 1:04 pm
  73. Is using a JS packer a security threat? says:PingBack from http://blogsurfer.net/7406/is-using-a-js-packer-a-security-threat-2.html
  74. Log in to Reply
  75. January 27, 2008 at 12:33 am
  76. Is using a JS packer a security threat? says:PingBack from http://blogsurfer.net/7518/is-using-a-js-packer-a-security-threat-3.html
  77. Log in to Reply
  78. January 27, 2008 at 9:31 am
  79. Don’t build your Web site in a vacuum says:PingBack from http://blogsurfer.net/7618/dont-build-your-web-site-in-a-vacuum-56.html
  80. Log in to Reply
  81. January 27, 2008 at 5:33 pm
  82. WordPress Admin Theme: Deconstructed says:PingBack from http://blogsurfer.net/7663/wordpress-admin-theme-deconstructed.html
  83. Log in to Reply
  84. January 27, 2008 at 9:10 pm
  85. Is using a JS packer a security threat? says:PingBack from http://blogsurfer.net/7923/is-using-a-js-packer-a-security-threat-4.html
  86. Log in to Reply
  87. January 29, 2008 at 12:32 am
  88. Manipulating innerHTML removes events says:PingBack from http://blogsurfer.net/8079/manipulating-innerhtml-removes-events-70.html
  89. Log in to Reply
  90. January 29, 2008 at 2:02 pm
  91. Web Content: Not just YOUR words and pictures says:PingBack from http://blogsurfer.net/8135/web-content-not-just-your-words-and-pictures-44.html
  92. Log in to Reply
  93. January 29, 2008 at 8:35 pm
  94. Our new addition says:PingBack from http://blogsurfer.net/8500/our-new-addition-39.html
  95. Log in to Reply
  96. January 31, 2008 at 7:03 am
  97. Performance web &raquo; Archive du blog &raquo; JSON ? says:PingBack from http://performance.survol.fr/2008/04/json/
  98. Log in to Reply
  99. April 25, 2008 at 1:17 pm
  100. Ajax performance analysis – Blue Box Sols says:PingBack from http://blueboxsols.com/?p=1813
  101. Log in to Reply
  102. September 10, 2008 at 1:09 pm
  103. Sergio Pereira says:This post is part of a series called JavaScript Demystified . I'm pretty sure by now you have heard
  104. Log in to Reply
  105. March 31, 2009 at 6:27 pm
  106. linkfeedr &raquo; Blog Archive &raquo; JavaScript: Avoid the Evil eval – RSS Indexer (beta) says:PingBack from http://www.linkfeedr.com/development/140126/javascript-avoid-the-evil-eval.html
  107. Log in to Reply
  108. May 22, 2009 at 7:02 pm
  109. mr.tang says:oh,I can’t understand.my english is pool enough
  110. July 13, 2012 at 12:05 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s