I think that this is a common pitfall and an important question, if you're reading this and anything is unclear please let me know in the comments.
In short
a; - will throw a reference error because it's trying to access an undefined variable
function() { return a; } )(); - this is exactly like the case above, it's an access to an undefined variable
object.a - will return undefined, we're not trying to access an undefined variable here, but rather the property of a known object, this is different
(function(a) { return a; } )(); - will return undefined, a is a parameter here and not an undefined variable, it will be assigned the actual language primitive value type undefined.
Let's dig a little bit deeper shall we?
The spec
Let's see what the language specification has to say about all these cases:
Undeclared variable reference
The spec states here:
If IsUnresolvableReference(V), throw a ReferenceError exception.
The spec states:
IsUnresolvableReference(V). Returns true if the base value is undefined and false otherwise.
This is why the following happens:
a; // ReferenceError: a is not defined
Since the base value is not defined, it throws a reference error as the spec specifies.
Undeclared object property
In an object, base is not undefined (it's the object) so it's all good and no error is thrown. It is resolved as such:
The following [[Get]] internal method is used by GetValue when V is a property reference with a primitive base value. It is called using base as its this value and with property P as its argument. The following steps are taken:
Let O be ToObject(base).
Let desc be the result of calling the [[GetProperty]] internal method of O with property name P.
If desc is undefined, return undefined.
Which, is why you see:
window.a; // undefined
Function parameter
The other case - parameter is completely different, the parameter exists, but its value is set to the primitive value type undefined. There is a difference between existing and being undefined and not existing :)
This is specified here:
If n is greater than argCount, let v be undefined otherwise let v be the value of the n’th element of args.
Which is why:
(function(a) { return a; } )(); // returns undefined
undefined. It is not a property ofwindow, but a local variable.function foo() { foo(); }<--- here is a self-invocationwindow.neverDeclaredOrSet===undefinedbut you can't check a variable in the same way. You can check variables like thistypeof(someVar)==="undefined", that won't throw an error. stackoverflow.com/questions/17287905/…