views:

160

answers:

6
+4  Q: 

eval is evil issue

Using JSlint to validate my javascript.

I am getting an error saying eval is evil! Why is this and is there an alternative I can use?

Here is an example of where I am using eval and would like a workaround for it.

I have an array like this:

var Resources = {
message_1: 'Message 1',
message_2: 'Message 2',
message_3: 'Message 3',
message_4: 'Message 4'
};

I have a function (functionResult) that returns a number, either 1, 2, 3 or 4. So what I want to do in the following line of code is get the Resource in the array that there message ends in the result of my function.

$('#divPresenter').html(eval($.validator.format('Resources.message_{0}', functionResult)));

Any ideas how I could remove eval and replace with something else?

+8  A: 

http://blogs.msdn.com/b/ericlippert/archive/2003/11/01/53329.aspx

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.

jnpcl
Hmmm, Microsoft. These are the same people that don't seem to be able to use `strcpy` safely, instead using `strcpy_s` et al (which is _far_ from safe, BTW), so I'm not sure I'd put too much value into their opinions :-)
paxdiablo
opinions are fine.. it's their code that worries me.
jnpcl
+3  A: 

JS Lint incorporates what Douglas Crockford considers to be the best practices for JavaScript. One of the functions he strongly discourages the use of is eval. I believe he considers it to be slow and insecure.

There could be many potential alternatives, depending on the code in question. If you'd like to post the section of your code which uses eval, we can give more specific advice.

Alex JL
+1 for not making a blanket assertion. `eval` is as evil as `goto` or multiple returns from a function (i.e, only evil if misused). In that sense, cutlery and hammers are evil as well :-) A good craftsman understands and knows the limitations and dangers of his tools.
paxdiablo
+3  A: 

If you are trying to use eval to turn strings into JSON objects, perhaps try a JSON parser lib (I've never used it but it looks reasonable).

Jared Updike
+5  A: 

It's evil because it lets you execute a string as code, and who knows where that string came from or what it contains.

And yes, 99.9% of the time, there are better alternatives (what exactly these are depends on what you're using eval for). The remaining 0.1% of the time, you really have no choice but to use eval, and in such cases, you need to be extremely cautious.

casablanca
Exactly. If you have parsed or otherwise verified that the string is safely, then eval is not a huge problem. That's how the parser I linked to in my answer works. Why? Perhaps because 'eval' is fast -- written in a lower level language than JavaScript, usually C or C++.
Jared Updike
+6  A: 

Instead of:

eval($.validator.format('Resources.message_{0}', functionResult))

just use:

Resources["message_" + functionResult]

All objects in JavaScript are really associative arrays (aka hashes), and the dot syntax (a.b) is just syntactic sugar for looking something up in the hash (a['b']). So you don't need eval at all; just build the key as a string, and look up your value using that key.

Joe White
I was going to post exactly this, but I went and built an example first: http://www.boogdesign.com/examples/array.html
robertc
+2  A: 

I'm not entirely clear on what you're doing, but it looks like
$('#divPresenter').html(eval($.validator.format('Resources.message_{0}', functionResult)));
can be written as
$('#divPresenter').html(Resources["message_" + functionResult]);

Gabe