JavaScript: Avoid the Evil eval
I'm pretty sure by now you have heard at least once that eval
is evil. Some
nuggets from Eric Lippert's post:
if you are considering using eval then there is probably a better way
People, eval starts a compiler.
I'm also pretty sure I don't need to tell you that anytime you have an explicit eval()
in your
code, there's a good chance it's there because
you're not taking JavaScript seriously yet.
//mandatory square brackets notation example //------------------------------------------ var myObject = new MyObject(); var prop1 = eval( 'myObject.' + somePropertyName ); // BAD! var prop2 = myObject[ somePropertyName ]; // Better
That's not the end of all eval()
At this point some people might be feeling relieved: "Phew! That was
easier than it sounded. Getting rid of eval is a piece of cake." Well,
I'm not going to say it's significantly harder than that, but we're not
done prunning eval()
from our code just yet.
You see, eval()
is like that coward opponent that sneaks in the
dark to attack you from behind. Let's find some of eval
's
favorite hiding places.
There's a time when you need a timer
Two very popular JavaScript functions used to create timers are setTimeout()
and
setInterval()
. Here's how you still find code being written to use them.
function doSomething(someValue){ //... } setTimeout("doSomething('3 seconds elapsed. Time is up.');", 3000);
As it turns out, this is just another occurrence of eval()
revealing
how incompetent we can still be in this programming language. Here's
a better way to write that code.
setTimeout( function(){ doSomething('3 seconds elapsed. Time is up.'); }, 3000);
Thank God I didn't know functions had constructors
The other secret place that eval()
likes to hang out is
in the Function
constructor. Fortunately this isn't exactly a
popular way of creating functions. I'll say it: I didn't even know about
this constructor until less than a couple of years ago.
So, in case you don't know what I'm talking about here, I'll show you how to use the function constructor just to imemdiately tell you to not do it.
var sum = new Function('op1', 'op2', 'return op1 + op2;'); var result = sum(10, 20); // ==> 30
The above code is roughly equivalent to the explicit eval()
usage below.
eval("var sum = function (op1, op2) { return op1 + op2; }"); var result = sum(10, 20); // ==> 30
We don't come up with the need to use the function constructor often, but I'll
admit that when we do, it's usually hard to replace it with another way that
doesn't use eval()
.
eval()
in some ways that I just pointed out to be unnecessary. If that is of any comfort to anyone
that has done the same in the past, there you have probably the largest deployment of misused eval()
I know of.