This paragraph is from the book JavaScript: The Definitive Guide, 6th edition, page 58:
When any identifier appears by itself in a program, JavaScript assumes it is a variable and looks up its value. If no variable with that name exists, the expression evaluates to the
undefinedvalue. In the strict mode of ECMAScript 5, however, an attempt to evaluate a nonexistent variable throws a ReferenceError instead.
First, let me explain how I interpret some of the phrases used in the paragraph.
"... identifier appears by itself in a program, ...":
I assume the author means the case where an identifier is parsed as an expression (in which case identifier resolution is performed). For example:
function func ( arg ) {
var local = helper( arg );
}
Here func, arg (which appears twice), local, and helper are all identifiers, but only helper and arg (only in its second appearance!) are expressions. Thus, only those two identifiers can cause a reference error.
"... no variable with that name exists ..." and "nonexistent variable":
I assume, the author means an identifier which evaluates to an unresolvable reference.
Now, correct me if I'm wrong but...
When an identifier which is parsed as an expression (a PrimaryExpression to be precise) is evaluated, identifier resolution is performed. The result of this process is always a value of the type Reference. In other words, the identifier will evaluate to a reference.
A reference has a base value and a referenced name. The referenced name is the text of the identifier and the base value is the environment record that has a binding for that name (the scope that contains such a variable). However, if identifier resolution fails to resolve the referenced name, the base value of the reference will be the undefined value.
So, a "nonexistent variable" therefore evaluates to a reference which base value is undefined.
Notice how the evaluation of a nonexistent variable does not throw a reference error. The error is thrown later when the interpreter retrieves the value of the reference (via GetValue()). This, however, may not always occur - for instance, typeof x won't retrieve the value of the reference if x evaluates to an unresolvable reference, and thus, a reference error is not thrown.
The paragraph quoted at the beginning of my question, states that in non-strict code, nonexistent variables evaluate to undefined, whereas in strict code evaluation of such an identifier throws a reference error. I believe that both these statements are incorrect - an nonexistent variable evaluates to a reference with a base value of undefined, and a reference error is not thrown in strict mode.
When the interpreter tries to retrieve the value of such a reference (which may or may not occur depending on the "outer" expression or statement in which the identifier appears in), a reference error is thrown. This behavior does not differ between non-strict and strict mode.
So, is the paragraph correct? If not, have I correctly identified the mistake(s)? (Also, if there is a mistake in my text, please correct me.)
Does a “nonexistent variable” evaluate to the “undefined” value in non-strict code?
> foo;
ReferenceError: foo is not defined
> var x = foo;
ReferenceError: foo is not defined
This behaviour is also true in strict mode:
> (function () { "use strict"; foo; }());
ReferenceError: foo is not defined
> (function () { "use strict"; var x = foo; }());
ReferenceError: foo is not defined
The only difference that I know of between strict mode and non-strict mode in terms of variable resolution is that when assigning a variable, if the variable is not declared, a ReferenceError is thrown in strict mode, however in non-strict mode a global variable is implicitly created.
Annex C (The strict mode of ECMAScript):
Assignment to an undeclared identifier or otherwise unresolvable reference does not create a property in the global object. When a simple assignment occurs within strict mode code, its LeftHandSide must not evaluate to an unresolvable Reference. If it does a ReferenceError exception is thrown (8.7.2).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With