Herman Tran
Herman Tran

Reputation: 1591

Undefined vs. defined window property in JavaScript

What is the difference between the following two statements (in the context of the global window)?

(function() { return a; } )(); // ReferenceError: a is not defined
(function(a) { return a; } )(); // returns undefined

I assume it has something to do with the following:

  a; // ReferenceError: a is not defined
  window.a; // undefined

It seems the second function goes up the scope chain and ends at the global window scope, where a is not a property of window and thus returns undefined. But shouldn't the first function also do the same and return undefined as well?

I found this SO question about undefined vs. not defined, but it seems to apply more relating to variables and not about properties in the window scope.

Upvotes: 1

Views: 1385

Answers (2)

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276306

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

Upvotes: 6

user229044
user229044

Reputation: 239301

You're really over-thinking your second case: (function(a) { return a; } )(); // returns undefined

Yes, but it has nothing to do with this:

... goes up the scope chain and ends at the global window scope, where a is not a property of window and thus returns undefined

You defined a parameter for the function, named a. Because you didn't supply a value, it is undefined. It's really that simple.

Upvotes: 1

Related Questions