116
Description
eval()
is a global method that evaluates a string of JavaScript code. If
code
contains an ex-
pression,
eval
evaluates the expression and returns its value. (Some expressions, such as object
and function literals look like statements and must be enclosed in parentheses when passed
to
eval()
in order to resolve the ambiguity.) If
code
contains a JavaScript statement or state-
ments,
eval()
executes those statements and returns the value, if any, returned by the last
statement. If
code
does not return any value,
eval()
returns
undefined
. Finally, if
code
throws
an exception,
eval()
passes that exception on to the caller.
eval()
behaves different in ECMAScript 3 and ECMAScript 5, and in ECMAScript 5, it be-
haves differently in strict mode and non-strict mode, and a minor digression is necessary in
order to explain these differences. It is much easier to implement efficient interpreters when
a programming language defines
eval
as an operator instead of as a function. JavaScript’s
eval
is a function, but for the sake of efficiency, the language draws a distinction between
direct, operator-like calls to
eval()
and indirect calls. A direct call uses the identifier
eval
directly and, if you removed the parentheses, it would look like
eval
was an operator. Any
other invocation of
eval()
is an indirect call. If you assign the
eval()
function to a variable
with a different name and invoke it through that variable, it is an indirect call. Similarly, if
you invoke eval() as a method of the global object, it is an indirect call.
With that distinction between direct and indirect calls made, we can document the behavior
of
eval()
like this:
Direct call, ES3 and ES5 non-strict mode
eval()
evaluates
code
in the current lexical scope. If
code
contains variable or function
declarations they are defined in the local scope. This is the normal use-case for
eval()
.
Indirect call, ES3
The ECMAScript 3 specification allows interpreters to throw an EvalError for any indirect
call to
eval()
. Implementations of ES3 don’t generally do this in practice, but indirect
calls should be avoided.
Indirect call, ES5
In ECMAScript 5, indirect calls to
eval()
must not throw an EvalError, and instead must
evaluate
code
in the global scope, ignoring any local variables in the current lexical scope.
In ES5, we can assign
var geval = eval;
, then we can use
geval()
to evaluate
code
in the
global scope.
Direct or Indirect call, strict mode
In strict mode variable and function definitions in
code
are defined in a private scope that
lasts only for the duration of the
eval()
call. This means that direct calls to
eval()
in
strict mode cannot alter the lexical scope and indirect calls in strict mode cannot alter
the global scope. These rules apply if the invocation of
eval()
is in strict mode, or if
code
begins with a “use strict” directive.
eval()
provides a very powerful capability to the JavaScript language, but its use is infrequent
in real-world programs. Obvious uses are to write programs that act as recursive JavaScript
interpreters and to write programs that dynamically generate and evaluate JavaScript code.
Most JavaScript functions that expect string arguments convert whatever value they are passed
to a string before proceeding.
eval()
does not behave like this: if
code
is not a primitive string
eval()
Core JavaScript Reference | 773
Core JavaScript
Reference