Chapter 28
Evaluation and Compilation
Evaluating a String
The eval() function is the easiest way to evaluate a string expression. There
are, however, several other ways:
var abc = "def"
document.write(abc)// 1
document.write("<BR>")
document.write(eval("abc"))// 2
document.write("<BR>")
document.write(window.abc) // 3
document.write("<BR>")
document.write(window["abc"]) // 4
document.write("<BR>")
document.write(window.eval("abc")) // 5
In the preceding script segment, all five lines (1, 2, 3, 4, 5) print the same output: def
(except for the fifth one, due to a bug).
Line 1 The document.write() method automatically evaluates
its argument, whether it is stored in a variable or handed to the function in the form of
a literal. In this particular case, we hand the function a data structure (a variable),
which evaluates to def. This method always evaluates the argument, so you must
surround a string literal with quotes (of any type).
Line 2 The eval() function evaluates its argument and
returns it as is. Unlike the document.write() function, except for returning it, eval()
does not do anything with the value. In this case, the function returns abc (not "abc"),
and document.write(eval("abc")) is then equivalent to document.write(abc),
which outputs def, as explained above.
Line 3 Since all variables in a document are actual properties of the
window object, the variable abc can be specified with a complete object
reference, as shown on this line.
Line 4 You can use the array notation instead of the “dot” syntax
(window["abc"] is equivalent to window.abc). Since the square
brackets evaluate their content, you should place a quoted string in between.
Line 5 Based on the preceding discussion, window.eval("abc")
is equivalent to window.abc which outputs def on Navigator. On Microsoft
Internet Explorer 3.0, however, this line prints abc.
Here is another set of slightly more complicated statements:
var abc = "def"
var def = "abc"
document.write(eval('eval("abc")'))// 1
document.write("<BR>")
document.write(eval(eval("abc"))) // 2
document.write("<BR>")
document.write(eval('window.eval("def")')) // 3
document.write("<BR>")
document.write(eval(window.eval("def"))) // 4
document.write("<BR>")
document.write(window[eval("def")])// 5
document.write("<BR>")
document.write(eval(window[eval("def")])) // 6
These statements output different strings, as explained below.
Line 1 eval('eval("abc")') evaluates to eval("abc")
because the top-level eval() “removes” the quotes. The expression eval("abc")
evaluates to abc, so the output of this statement is "def".
Line 2 eval("abc") is evaluated first, because the
innermost function call is always evaluated before any other function call in the same
expression. (In the previous statement, as the “inner” function call is actually a
string, there is only one function call besides the document.write() statement.)
Therefore, eval("abc") evaluates to abc, and eval(eval("abc"))
evaluates to eval("def"), which, in turn, evaluates to def.
The statement’s output is then "def".
Line 3 You should have guessed that the output of this statement
differs from browser to browser (IE and Navigator). On both browsers, eval('window.eval("def")')
evaluates to window.eval("def"). This statement evaluates to "def"
on MSIE, and "abc" on Netscape Navigator. (See the explanation for the
last statement in the previous script segment.)
Line 4 We already know that window.eval("def")
evaluates to "def" on MSIE, and "abc" on Netscape
Navigator. Therefore, eval(window.eval("def")) evaluates to the exact
opposite: "abc" on MSIE, and "def" on Netscape
Navigator.
Line 5 eval("def") evaluates to def, so window[eval("def")]
evaluates to window[def], which evaluates to window["abc"].
Therefore, this statement prints "def".
Line 6 eval(window[eval("def")]) is actually the
value handed to the document.write() method in the previous statement, evaluated
by another eval() function call. Therefore, it evaluates to eval("def"),
which evaluates to def, so this statement prints "abc".
You should now know exactly how Netscape Navigator handles string evaluation. When it
comes to MSIE 3.0x, you cannot always know what is going to happen, so the best solution
is to simply try it. Sometimes, you’ll have to work around a bug by using an alternative
expression, as is demonstrated by the Color Center application in Chapter 26.
Function References and Calls
Take a look at the following function definition:
function multiply(op1, op2) {
var result = op1 * op2
return result
}
A function call is an expression that invokes a function. The following statement, for
example, consists of a function call:
var num = multiply(5, 8)
Function calls are very convenient, because you can specify arguments for the function
and accept the returned value. JavaScript, however, does not always permit function calls.
You cannot use, for example, a function call as a constructor function’s method.
Instead, you should use a function reference:
function makeOperator() {
this.multiply = multiply // not multiply()
}