The eval function is a powerful and easy way to dynamically generate code, so what are the caveats?
Improper use of eval opens up your
code for injection attacks
Debugging can be more challenging
(no line numbers, etc.)
eval'd code executes slower (no opportunity to compile/cache eval'd code)
Edit: As #Jeff Walden points out in comments, #3 is less true today than it was in 2008. However, while some caching of compiled scripts may happen this will only be limited to scripts that are eval'd repeated with no modification. A more likely scenario is that you are eval'ing scripts that have undergone slight modification each time and as such could not be cached. Let's just say that SOME eval'd code executes more slowly.
eval isn't always evil. There are times where it's perfectly appropriate.
However, eval is currently and historically massively over-used by people who don't know what they're doing. That includes people writing JavaScript tutorials, unfortunately, and in some cases this can indeed have security consequences - or, more often, simple bugs. So the more we can do to throw a question mark over eval, the better. Any time you use eval you need to sanity-check what you're doing, because chances are you could be doing it a better, safer, cleaner way.
To give an all-too-typical example, to set the colour of an element with an id stored in the variable 'potato':
eval('document.' + potato + '.style.color = "red"');
If the authors of the kind of code above had a clue about the basics of how JavaScript objects work, they'd have realised that square brackets can be used instead of literal dot-names, obviating the need for eval:
document[potato].style.color = 'red';
...which is much easier to read as well as less potentially buggy.
(But then, someone who /really/ knew what they were doing would say:
document.getElementById(potato).style.color = 'red';
which is more reliable than the dodgy old trick of accessing DOM elements straight out of the document object.)
I believe it's because it can execute any JavaScript function from a string. Using it makes it easier for people to inject rogue code into the application.
It's generally only an issue if you're passing eval user input.
Two points come to mind:
Security (but as long as you generate the string to be evaluated yourself, this might be a non-issue)
Performance: until the code to be executed is unknown, it cannot be optimized. (about javascript and performance, certainly Steve Yegge's presentation)
Passing user input to eval() is a security risk, but also each invocation of eval() creates a new instance of the JavaScript interpreter. This can be a resource hog.
Mainly, it's a lot harder to maintain and debug. It's like a goto. You can use it, but it makes it harder to find problems and harder on the people who may need to make changes later.
One thing to keep in mind is that you can often use eval() to execute code in an otherwise restricted environment - social networking sites that block specific JavaScript functions can sometimes be fooled by breaking them up in an eval block -
eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');
So if you're looking to run some JavaScript code where it might not otherwise be allowed (Myspace, I'm looking at you...) then eval() can be a useful trick.
However, for all the reasons mentioned above, you shouldn't use it for your own code, where you have complete control - it's just not necessary, and better-off relegated to the 'tricky JavaScript hacks' shelf.
Unless you let eval() a dynamic content (through cgi or input), it is as safe and solid as all other JavaScript in your page.
Along with the rest of the answers, I don't think eval statements can have advanced minimization.
It is a possible security risk, it has a different scope of execution, and is quite inefficient, as it creates an entirely new scripting environment for the execution of the code. See here for some more info: eval.
It is quite useful, though, and used with moderation can add a lot of good functionality.
Unless you are 100% sure that the code being evaluated is from a trusted source (usually your own application) then it's a surefire way of exposing your system to a cross-site scripting attack.
It's not necessarily that bad provided you know what context you're using it in.
If your application is using eval() to create an object from some JSON which has come back from an XMLHttpRequest to your own site, created by your trusted server-side code, it's probably not a problem.
Untrusted client-side JavaScript code can't do that much anyway. Provided the thing you're executing eval() on has come from a reasonable source, you're fine.
It greatly reduces your level of confidence about security.
If you want the user to input some logical functions and evaluate for AND the OR then the JavaScript eval function is perfect. I can accept two strings and eval(uate) string1 === string2, etc.
If you spot the use of eval() in your code, remember the mantra “eval() is evil.”
This
function takes an arbitrary string and executes it as JavaScript code. When the code in
question is known beforehand (not determined at runtime), there’s no reason to use
eval().
If the code is dynamically generated at runtime, there’s often a better way to
achieve the goal without eval().
For example, just using square bracket notation to
access dynamic properties is better and simpler:
// antipattern
var property = "name";
alert(eval("obj." + property));
// preferred
var property = "name";
alert(obj[property]);
Using eval() also has security implications, because you might be executing code (for
example coming from the network) that has been tampered with.
This is a common antipattern when dealing with a JSON response from an Ajax request.
In those cases
it’s better to use the browsers’ built-in methods to parse the JSON response to make
sure it’s safe and valid. For browsers that don’t support JSON.parse() natively, you can
use a library from JSON.org.
It’s also important to remember that passing strings to setInterval(), setTimeout(),
and the Function() constructor is, for the most part, similar to using eval() and therefore
should be avoided.
Behind the scenes, JavaScript still has to evaluate and execute
the string you pass as programming code:
// antipatterns
setTimeout("myFunc()", 1000);
setTimeout("myFunc(1, 2, 3)", 1000);
// preferred
setTimeout(myFunc, 1000);
setTimeout(function () {
myFunc(1, 2, 3);
}, 1000);
Using the new Function() constructor is similar to eval() and should be approached
with care. It could be a powerful construct but is often misused.
If you absolutely must
use eval(), you can consider using new Function() instead.
There is a small potential
benefit because the code evaluated in new Function() will be running in a local function
scope, so any variables defined with var in the code being evaluated will not become
globals automatically.
Another way to prevent automatic globals is to wrap the
eval() call into an immediate function.
EDIT: As Benjie's comment suggests, this no longer seems to be the case in chrome v108, it would seem that chrome can now handle garbage collection of evaled scripts.
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
Garbage collection
The browsers garbage collection has no idea if the code that's eval'ed can be removed from memory so it just keeps it stored until the page is reloaded.
Not too bad if your users are only on your page shortly, but it can be a problem for webapp's.
Here's a script to demo the problem
https://jsfiddle.net/CynderRnAsh/qux1osnw/
document.getElementById("evalLeak").onclick = (e) => {
for(let x = 0; x < 100; x++) {
eval(x.toString());
}
};
Something as simple as the above code causes a small amount of memory to be store until the app dies.
This is worse when the evaled script is a giant function, and called on interval.
Besides the possible security issues if you are executing user-submitted code, most of the time there's a better way that doesn't involve re-parsing the code every time it's executed. Anonymous functions or object properties can replace most uses of eval and are much safer and faster.
This may become more of an issue as the next generation of browsers come out with some flavor of a JavaScript compiler. Code executed via Eval may not perform as well as the rest of your JavaScript against these newer browsers. Someone should do some profiling.
This is one of good articles talking about eval and how it is not an evil:
http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/
I’m not saying you should go run out and start using eval()
everywhere. In fact, there are very few good use cases for running
eval() at all. There are definitely concerns with code clarity,
debugability, and certainly performance that should not be overlooked.
But you shouldn’t be afraid to use it when you have a case where
eval() makes sense. Try not using it first, but don’t let anyone scare
you into thinking your code is more fragile or less secure when eval()
is used appropriately.
eval() is very powerful and can be used to execute a JS statement or evaluate an expression. But the question isn't about the uses of eval() but lets just say some how the string you running with eval() is affected by a malicious party. At the end you will be running malicious code. With power comes great responsibility. So use it wisely is you are using it.
This isn't related much to eval() function but this article has pretty good information:
http://blogs.popart.com/2009/07/javascript-injection-attacks/
If you are looking for the basics of eval() look here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
The JavaScript Engine has a number of performance optimizations that it performs during the compilation phase. Some of these boil down to being able to essentially statically analyze the code as it lexes, and pre-determine where all the variable and function declarations are, so that it takes less effort to resolve identifiers during execution.
But if the Engine finds an eval(..) in the code, it essentially has to assume that all its awareness of identifier location may be invalid, because it cannot know at lexing time exactly what code you may pass to eval(..) to modify the lexical scope, or the contents of the object you may pass to with to create a new lexical scope to be consulted.
In other words, in the pessimistic sense, most of those optimizations it would make are pointless if eval(..) is present, so it simply doesn't perform the optimizations at all.
This explains it all.
Reference :
https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#eval
https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#performance
It's not always a bad idea. Take for example, code generation. I recently wrote a library called Hyperbars which bridges the gap between virtual-dom and handlebars. It does this by parsing a handlebars template and converting it to hyperscript which is subsequently used by virtual-dom. The hyperscript is generated as a string first and before returning it, eval() it to turn it into executable code. I have found eval() in this particular situation the exact opposite of evil.
Basically from
<div>
{{#each names}}
<span>{{this}}</span>
{{/each}}
</div>
To this
(function (state) {
var Runtime = Hyperbars.Runtime;
var context = state;
return h('div', {}, [Runtime.each(context['names'], context, function (context, parent, options) {
return [h('span', {}, [options['#index'], context])]
})])
}.bind({}))
The performance of eval() isn't an issue in a situation like this because you only need to interpret the generated string once and then reuse the executable output many times over.
You can see how the code generation was achieved if you're curious here.
I would go as far as to say that it doesn't really matter if you use eval() in javascript which is run in browsers.*(caveat)
All modern browsers have a developer console where you can execute arbitrary javascript anyway and any semi-smart developer can look at your JS source and put whatever bits of it they need to into the dev console to do what they wish.
*As long as your server endpoints have the correct validation & sanitisation of user supplied values, it should not matter what gets parsed and eval'd in your client side javascript.
If you were to ask if it's suitable to use eval() in PHP however, the answer is NO, unless you whitelist any values which may be passed to your eval statement.
I won't attempt to refute anything said heretofore, but i will offer this use of eval() that (as far as I know) can't be done any other way. There's probably other ways to code this, and probably ways to optimize it, but this is done longhand and without any bells and whistles for clarity sake to illustrate a use of eval that really doesn't have any other alternatives. That is: dynamical (or more accurately) programmically-created object names (as opposed to values).
//Place this in a common/global JS lib:
var NS = function(namespace){
var namespaceParts = String(namespace).split(".");
var namespaceToTest = "";
for(var i = 0; i < namespaceParts.length; i++){
if(i === 0){
namespaceToTest = namespaceParts[i];
}
else{
namespaceToTest = namespaceToTest + "." + namespaceParts[i];
}
if(eval('typeof ' + namespaceToTest) === "undefined"){
eval(namespaceToTest + ' = {}');
}
}
return eval(namespace);
}
//Then, use this in your class definition libs:
NS('Root.Namespace').Class = function(settings){
//Class constructor code here
}
//some generic method:
Root.Namespace.Class.prototype.Method = function(args){
//Code goes here
//this.MyOtherMethod("foo")); // => "foo"
return true;
}
//Then, in your applications, use this to instantiate an instance of your class:
var anInstanceOfClass = new Root.Namespace.Class(settings);
EDIT: by the way, I wouldn't suggest (for all the security reasons pointed out heretofore) that you base you object names on user input. I can't imagine any good reason you'd want to do that though. Still, thought I'd point it out that it wouldn't be a good idea :)
This may be a obvious question, but I was wondering if there was an efficiency difference between declaring something in a one time use variable or simply executing the code once (rather then storing it then using it). For example
var rowId = 3,
updateStuff(rowId);
VS
updateStuff(3);
I think that worrying about performance in this instance is largely irrelevant. These sorts of micro-optimizations don't really buy you all that much. In my opinion, the readability of the code here is more important, since it's better to identify the 3 as rowId than leaving it as a magic number.
If you are really concerned about optimization, minimizing your code with something like Google Closure would help; it has many tools that will help you make your code more efficient.
If you were using google closure to compile and if you annotated the var as a constant (as it appears in your example), I suspect the compiler would remove the constant and replace it with the literal.
My advice is to pick the readable option and if you really need the micro-optimizations and reduction in source size, use the google closure compiler or a minifier-- a tool is more likeley to accumulate enough micro-optimizations to make something noticeably faster, although I'd guess most of the saved milliseconds would come from reduced network time from minification.
And var declarations do take time and if you added that var to the global namespace, then there is one more thing that will be searched during resolving names.
With a modern browser that compiles your code, the generated code will be exactly the same unless the variable is referenced somewhere else also.
Even with an old browser if there is a difference it won't be something to worry about.
EDIT:
delete does not apply to non-objects, therefore my initial response was wrong. Furtermore since the variable rowId is declared with the flag var it will be cleaned up by the garbage collection. Was it on the other hand defined without, it would live for the duration of the page / application.
source: http://lostechies.com/derickbailey/2012/03/19/backbone-js-and-javascript-garbage-collection/
The variable rowId will be kept in memory and will not be released by the garbage collector since it's referenced to. Unless you release it afterwards like below it will be there till the end of the programs life. Also remember it take time to create the variable (minimal, but you asked)
var rowId = 3
updateStuff(rowId);
delete rowId
With efficiency in mind, then yes there is a difference. Your second example is the quickest and doesn't spend any extra resources.
OBS. Some languages do optimize code as such and simply remove the sequence, but I strongly doubt that JavaScript does so.
I have been working on web project for past 4 months. To optimise the code performance we have used a pattern. My doubt is, does it actually boost performance or not?
when ever we have to use this object we assign it to a local variable, and use that.
function someFunction()
{
var thisObject = this;
//use thisObject in all following the code.
}
the assumption here is that, assigning this object to a local stack variable will boost the performance.
I have not seen this type of coding anywhere so doubt if it is of no use.
EDIT: I know that assigning this object to local variable is done for preserving object, but that is not our case.
While this is a common practice in Javascript it's not done for performance reasons. The saving of the this object in another named local is usually done to preserve the value of this across callbacks which are defined within the function.
function someFunction() {
var thisObject = this;
var someCallback = function() {
console.log(thisObject === this); // Could print true or false
};
return someCallback;
}
Whether or not thisObject === this evaluates to true will depend on how it's called
var o = {}
o.someFunction = someFunction();
var callback = o.someFunction();
callback(); // prints false
callback.call(o); // prints true
As with ALL performance questions, they should be examined by actually measuring the performance. In a rather simple test case (your actual code might vary some), I find mixed results across the browsers:
Chrome and Firefox don't differ very much between the two tests, but the slight difference is in opposite directions between the two. IE9 shows the test using a saved copy of this which I called self to be significantly slower.
Without a significant and consistent performance difference in Chrome and Firefox and IE9 showing the this test case to be substantially faster, I think you can conclude that the design pattern you asked about is not delivering a consistent performance boost across browsers.
In my code, I save a copy of this to another variable only when I need it for a consistent reference to the original object inside of inline event handlers, callbacks or methods where this has been set to something else. In other words, I only apply this design pattern when needed.
In a previous discussion of this design pattern here on SO, it was concluded that some libraries use this design pattern in order to allow additional minimization because this cannot be minified below the four characters that it takes up, but assigning it to a locally variable can be minified to a single character variable name.
Even when this kind of optimization has an (positive) effect, it is very likely to depend on the interpreter.
An other release may revert the results.
However, in the end you should measure, not guess.
After doing some research on the subject, I've been experimenting a lot with patterns to organize my jQuery code (Rebecca Murphy did a presentation on this at the jQuery Conference for example).
Yesterday I checked the (revealing) module pattern. The outcome looks a bit reminiscent of the YUI syntax I think:
//global namespace MyNameSpace
if(typeof MNS=="undefined"||!MNS){var MNS={};}
//obfuscate module, just serving as a very simple example
MNS.obfuscate = function(){
//function to create an email address from obfuscated '#'
var email = function(){
$('span.email').each(function(){
var emailAddress = $(this).html().replace(' [ # ] ','#');
$(this).html('' + emailAddress + '');
});
};
return {
email: email
};
}();
//using the module when the dom's ready
jQuery(document).ready(function($){
MNS.obfuscate.email();
});
In the end I had several modules. Some naturally included "private members", which in this case means variables and/or functions which were only of importance for other functions within this module, and thus didn't end up in the return statement.
I thought having connected parts of my code (everything which has to do with the search for example) combined in a module makes sense, gives the whole thing structure.
But after writing this, I read an article by John (Resig), where he also writes about the performance of the module pattern:
"Instantiating a function with a bunch of prototype properties is very, very, fast. It completely blows the Module pattern, and similar, out of the water. Thus, if you have a frequently-accessed function (returning an object) that you want people to interact with, then it's to your advantage to have the object properties be in the prototype chain and instantiate it. Here it is, in code:
// Very fast
function User(){}
User.prototype = { /* Lots of properties ... */ };
// Very slow
function User(){
return { /* Lots of properties */ };
}
(John mentions he is not against the module pattern "per se" though - just to let you know :)
Then I wasn't sure anymore if I was going into the right direction with my code. The thing is: I don't really need any private members, and I also don't think I need inheritance for the time being.
All I want for now is a readable/maintainable pattern. I guess this boils down to personal preference to a certain extend, but I don't wanna end up with readable code which has (rather serious) performance issues.
I'm no JavaScript expert and thus even less of an expert when it comes to performance testing. So first, I don't really know in how far the things John mentioned ("frequently-accessed function (returning an object) that you want people to interact with", lots of properties, etc.) apply to my code. The documents my code interacts with are not huge, with 100s or 1000s of elements. So maybe it's not an issue at all.
But one thing which came to my mind is that instead of just having
$('span.email').each(function(){
var emailAddress = $(this).html().replace(' [ # ] ','#');
$(this).html('' + emailAddress + '');
});
(inside the domready function), I create two "extra" functions, obfuscate and email, due to the use of the module pattern. The creation of additional functions costs some time. The question is: will it be measurable in my case?
I'm not sure if a closure is created in my example above (in an interesting post on the jQuery forum I read the following: "There is a philosophical debate on whether an inner function creates a closure if it doesn't reference anything on an outer function's variable object..."), but I did have closures in my real code. And even though I don't think I had any circular references in there, I don't know in how far this could lead to high(er) memory consumption/problems with garbage collection.
I'd really like to hear your input on this, and maybe see some examples of your code. Also, which tools do you prefer to get information on execution time, memory and CPU usage?
I also don't think I need inheritance for the time being
Indeed. This doesn't really apply to using modules as a namespace. It's about class instance analogues.
Objects you create by making every instance from a completely new {name: member} object are less efficient than objects you create using new Class with Class.prototype.name= member. In the prototype case the member value is shared, resulting in lighter-weight instances.
In your example MNS is a singleton, so there is no benefit to be had by sharing members through a prototype.
I'm not sure if a closure is created in my example above
Yes, it is. Even when no variables are defined in the outer function, there is still a LexicalEnvironment and scope object created for the outer function, with this and arguments bound in it. A clever JS engine might be able to optimise it away, since every inner function must hide this and arguments with their own copies, but I'm not sure that any of the current JS implementations actually do that.
The performance difference, in any case, should be undetectable, since you aren't putting anything significant in the arguments. For a simple module pattern I don't think there's any harm.
Also, which tools do you prefer to get information on execution time, memory and CPU usage?
The place to start is simply to execute the code 10000 times in a for-loop and see how much bigger new Date().getTime() has got, executed several times on as many different browsers as you can get hold of.
$(this).html().replace(' [ # ] ','#');
(What is this supposed to do? At the moment it will read the HTML of the span into a new String, replace only the first instance of [ # ] with #, and return a new String value. It won't change the existing content in the DOM.)
How much Javascript do you have? In my experience, on sites with lots of Javascript code on the pages, performance problems generally come from code that actually does things. Generally, problems stem from trying to do too many things, or trying to do some particular thing really badly. An example would be trying to do stuff like bind handlers to elements in table rows (big tables) instead of using something like "live".
My point is that things like how your modules or functions or whatever get organized is almost certainly not going to pose any sort of real performance issue on your pages. What is motivating you to go to all this trouble?