I know that eval
and setTimeout
can both accept a string as the (1 st) parameter, and I know that I'd better not use this. I'm just curious why is there a difference:
!function() {
var foo = 123;
eval("alert(foo)");
}();
!function() {
var foo = 123;
setTimeout("alert(foo)", 0);
}();
the first would work, and the second will give an error: foo is not defined
How are they executed behind the scene?
I know that eval
and setTimeout
can both accept a string as the (1 st) parameter, and I know that I'd better not use this. I'm just curious why is there a difference:
!function() {
var foo = 123;
eval("alert(foo)");
}();
!function() {
var foo = 123;
setTimeout("alert(foo)", 0);
}();
the first would work, and the second will give an error: foo is not defined
How are they executed behind the scene?
See the reference of setTimeout
on MDN.
String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.
In contrast, the string literal passed to eval() is executed in the context of the call to eval.
setTimeout's eval
is additionally executed in global scope, so it's not aware of foo
.
Here's reference to back it up:
String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.
setTimeout takes more parameters than function reference and timeout. Anything entered past timeout will be passed to your function as a parameter.
setTimeout(myFunction(param1, param2), 0, param1, param2);
!function() {
var foo = 123;
eval("alert(foo)");
}();
When executing this code, javascript will pretend that line 3 says "alert(foo)". Foo is defined in the scope of the function.
!function() {
var foo = 123;
setTimeout("alert(foo)", 0);
}();
When executing this code, javascript will enter a new function; namely function() {alert(foo)}
. In the scope of that 'new' function, foo
is not defined.
As a plement to the correct answer, here is a call to eval
that would give you the same behavior, and error in this cases:
!function() {
var foo = 123;
window.eval("alert(foo)"); // <- note the window.eval, this is important and changes the behavior of the `eval` function
}();
!function() {
var foo = 123;
setTimeout("alert(foo)", 0);
}();
This blog post goes in depth on the different types of eval
: http://perfectionkills./global-eval-what-are-the-options/