Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does an undefined variable in Javascript sometimes evaluate to false and sometimes throw an uncaught ReferenceError?

Tags:

javascript

Everything I've ever read indicates that in Javascript, the boolean value of an undefined variable is False. I've used code like this hundreds of times:

if (!elem) {    ... } 

with the intent that if "elem" is undefined, the code in the block will execute. It usually works, but on occasion the browser will throw an error complaining about the undefined reference. This seems so basic, but I can't find the answer.

Is it that there's a difference between a variable that has not been defined and one that has been defined but which has a value of undefined? That seems completely unintuitive.

like image 272
Gullbyrd Avatar asked Apr 02 '12 17:04

Gullbyrd


People also ask

Does undefined evaluate to false JavaScript?

Description. A falsy value is something which evaluates to FALSE, for instance when checking a variable. There are only six falsey values in JavaScript: undefined , null , NaN , 0 , "" (empty string), and false of course.

Why is my JavaScript variable undefined?

A variable that has not been assigned a value is of type undefined . A method or statement also returns undefined if the variable that is being evaluated does not have an assigned value. A function returns undefined if a value was not returned .

What does undefined evaluate to in JavaScript?

The undefined property indicates that a variable has not been assigned a value, or not declared at all.

Does undefined evaluate to TRUE JavaScript?

Why does an undefined variable in Javascript sometimes evaluate to false and sometimes throw an uncaught ReferenceError? Bookmark this question. Show activity on this post. Everything I've ever read indicates that in Javascript, the boolean value of an undefined variable is False.


2 Answers

What is a ReferenceError?

As defined by ECMAScript 5, a ReferenceError indicates that an invalid reference has been detected. That doesn't say much by itself, so let's dig a little deeper.

Leaving aside strict mode, a ReferenceError occurs when the scripting engine is instructed to get the value of a reference that it cannot resolve the base value for:

A Reference is a resolved name binding. A Reference consists of three components, the base value, the referenced name and the Boolean valued strict reference flag. The base value is either undefined, an Object, a Boolean, a String, a Number, or an environment record (10.2.1). A base value of undefined indicates that the reference could not be resolved to a binding. The referenced name is a String.

When we are referencing a property, the base value is the object whose property we are referencing. When we are referencing a variable, the base value is unique for each execution context and it's called an environment record. When we reference something that is neither a property of the base object value nor a variable of the base environment record value, a ReferenceError occurs.

Consider what happens when you type foo in the console when no such variable exists: you get a ReferenceError because the base value is not resolvable. However, if you do var foo; foo.bar then you get a TypeError instead of a ReferenceError -- a subtle perhaps but very significant difference. This is because the base value was successfully resolved; however, it was of type undefined, and undefined does not have a property bar.

Guarding against ReferenceError

From the above it follows that to catch a ReferenceError before it occurs you have to make sure that the base value is resolvable. So if you want to check if foo is resolvable, do

if(this.foo) //... 

In the global context, this equals the window object so doing if (window.foo) is equivalent. In other execution contexts it does not make as much sense to use such a check because by definition it's an execution context your own code has created -- so you should be aware of which variables exist and which do not.

like image 182
Jon Avatar answered Sep 22 '22 04:09

Jon


Checking for undefined works for variables that have no value associated but if the variable itself hasn't been declared you can run into these reference issues.

if (typeof elem === "undefined") 

This is a far better check as doesn't run the risk of the reference issue as typeof isn't a method but a keyword within JavaScript.

like image 35
Kris Avatar answered Sep 25 '22 04:09

Kris