1

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.

5
  • 7
    For the second function it accepts a parameter but you passed nothing to it, so it is undefined. It is not a property of window, but a local variable. Commented Jun 25, 2013 at 2:45
  • Thanks Alvin! I totally forgot about testing for passing back a parameter to the function, seem to often misuse self-invoking functions Commented Jun 25, 2013 at 2:58
  • 2
    @hermantran: they are not self-invoking, but immediately executed. Self-invocation is when a function calls itself from its body. function foo() { foo(); } <--- here is a self-invocation Commented Jun 25, 2013 at 2:58
  • undefined variable and undefined value is not the same in JavaScript. You can check on an object if it has a property defined like window.neverDeclaredOrSet===undefined but you can't check a variable in the same way. You can check variables like this typeof(someVar)==="undefined", that won't throw an error. stackoverflow.com/questions/17287905/… Commented Jun 25, 2013 at 3:05
  • @zerkms thanks for the distinction, I definitely was under the impression that self-invoking and IIFE meant the same thing Commented Jun 25, 2013 at 3:11

2 Answers 2

6

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
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you Benjamin for the detailed post and spec reference! Very enlightening stuff
@hermantran I'm glad I could help, let me know if there is anything you don't understand here :) The language specification is pretty well written and there are constant attempts to make it even more readable, it's a good resource to check when in doubt :)
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.