Thrown for a loop by JavaScript’s ReferenceError
The other day I was talking to a couple of friends about a ReferenceError they were getting in some code they were running. They were just checking for the existence of a global variable. They were just doing this:
if(foo){
doSomething();
}
Would you expect that to work? If so, you’re better at this than I am. If foo is not defined, either in the current scope or globally, you’ll get a ReferenceError there. Why does this strike me as so inconsistent? Consider the following:
var foo = {};
if(foo.propertyThatDoesntExist){
doSomething();
}
If you check for the existence of a property of an object that doesn’t exist, it simply returns undefined. No error is thrown, your code doesn’t halt execution, things don’t explode. In fact, the interpreter will work its way up the scope chain from foo, looking for the missing property.
Now, consider this example:
var setImplicitGlobal = function(){
implicitGlobal = 'Are you sure this is what you wanted?';
}
setImplicitGlobal();
alert(implicitGlobal); // Alerts the string from above
So when we’re doing assignment and try to assign a value to an undefined variable, the interpreter assumes we wanted a new global variable and creates it for us. Despite the fact that this is almost never what anyone would reasonably want to happen.
Finally, consider the following:
if(foo){ // Reference error when foo has not been declared
doSomething();
}
if(window.foo){ // Undefined when foo window.foo has not been set.
doSomething()
}
So when we try to assign a value to an undeclared variable, the interpreter assumes we meant window.foo and creates it for us. But when we’re trying to read the same thing, it doesn’t make the same assumption, throws an error, and breaks our script even when we thought we were coding defensively.
What am I missing here? This is sort of inconsistent, is it not?
