Jump to content

Year

1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021

Day

24 Ways to impress your friends

JavaScript is an interpreted language, and like so many of its peers it includes the all powerful eval() function. eval() takes a string and executes it as if it were regular JavaScript code. It’s incredibly powerful and incredibly easy to abuse in ways that make your code slower and harder to maintain. As a general rule, if you’re using eval() there’s probably something wrong with your design.

Common mistakes

Here’s the classic misuse of eval(). You have a JavaScript object, foo, and you want to access a property on it – but you don’t know the name of the property until runtime. Here’s how NOT to do it:

var property = 'bar';
var value = eval('foo.' + property);

Yes it will work, but every time that piece of code runs JavaScript will have to kick back in to interpreter mode, slowing down your app. It’s also dirt ugly.

Here’s the right way of doing the above:

var property = 'bar';
var value = foo[property];

In JavaScript, square brackets act as an alternative to lookups using a dot. The only difference is that square bracket syntax expects a string.

Security issues

In any programming language you should be extremely cautious of executing code from an untrusted source. The same is true for JavaScript – you should be extremely cautious of running eval() against any code that may have been tampered with – for example, strings taken from the page query string. Executing untrusted code can leave you vulnerable to cross-site scripting attacks.

What’s it good for?

Some programmers say that eval() is B.A.D. – Broken As Designed – and should be removed from the language. However, there are some places in which it can dramatically simplify your code. A great example is for use with XMLHttpRequest, a component of the set of tools more popularly known as Ajax. XMLHttpRequest lets you make a call back to the server from JavaScript without refreshing the whole page. A simple way of using this is to have the server return JavaScript code which is then passed to eval(). Here is a simple function for doing exactly that – it takes the URL to some JavaScript code (or a server-side script that produces JavaScript) and loads and executes that code using XMLHttpRequest and eval().

function evalRequest(url) {
     var xmlhttp = new XMLHttpRequest();
     xmlhttp.onreadystatechange = function() {
          if (xmlhttp.readyState==4 && xmlhttp.status==200) {
               eval(xmlhttp.responseText);
          }
     }
     xmlhttp.open("GET", url, true);
     xmlhttp.send(null);
 }

If you want this to work with Internet Explorer you’ll need to include this compatibility patch.

About the author

Simon Willison works for Yahoo! as “UK Hacker Liaison” / multi-purpose web technologist. He blogs at http://simon.incutio.com/. He sometimes hacks on Django.

Like what you read?

Comments

Troy bloodynightmare.net

Very nice. People who develop apps should thing about the functions they use in any language before just using them.

Aaron Schmidt aaron.aminus3.com

I’ve always been afraid of eval just because it seems like such a hack. Thanks for outlining the alternatives.

Dustin Diaz www.dustindiaz.com

To think that there’s people out there that really do think it’s B.A.D…. oh well.

Anyway, Simon, thanks for putting up a great 7th day. I’ll pass this along to the Sunnyvale folk if they haven’t already found it.

Mee

Google Suggest also uses eval() when returning array of possible hits.

Should be used with thought, as pointed.

Alexey Feldgendler feldgendler.livejournal.com

The link http://www.scss.com.au/family/andrew/webdesign/xmlhttprequest/ is broken: 403 Forbidden.

brandon elbo.ws

eval() is great for JSON:

http://en.wikipedia.org/wiki/JSON

Justin Perkins www.iamjp.com

eval() doesn’t simplify your code, it just hides it inside CPU-intensive strings.

AJAX responses ought to be data, it seems funny to pass back Javascript (even if it’s just a function call) for execution.

bo bjelic.net

I agree with Justin. There are already some examples of using eval() with AJAX. I say it is just as “eval” missusage, executing magicly retrieved code… xmlhttp.responseText should stay text – parse it and do the work in the calling script.

Commenting is closed for this article.

About the author

Simon Willison

Simon Willison is a freelance client- and server-side Web developer and the co-creator of the Django Web framework. Simon's interests include OpenID and decentralised systems, unobtrusive JavaScript, rapid application development and RESTful Web Service APIs. Before going frelance Simon worked on Yahoo!'s Technology Development team, and prior to that at the Lawrence Journal-World, an award winning local newspaper in Kansas. Simon maintains a popular Web development weblog at simonwillison.net

Photo: Tom Coates

More information

In association with:

Perch - a really little cms

The easiest way to publish HTML5 websites your clients will love.

24 ways is an edgeofmyseat.com production. Edited by Drew McLellan and Brian Suda. Assisted by Anna Debenham and Owen Gregory. Design delivered by Made by Elephant. Possible only with the help of our dazzling authors. Grab our RSS feed. Follow us on Twitter, Facebook or Google+ for daily updates.


You are viewing a mobilized version of this site...
View original page here

Mobilized by Mowser Mowser