4

If I create an object like this:

var foo = foo || {};

There's no problem.

But this:

var foo = bar || {};

Produces the error:

Uncaught ReferenceError: bar is not defined 

Why doesn't the second snippet work when the first does?

6
  • Well, what is bar? You aren't declaring it. The latter example makes sense. Commented Aug 5, 2014 at 17:53
  • because you haven't defined bar? Commented Aug 5, 2014 at 17:53
  • @CaseyFalk I thought the point of the variable || {} syntax was to assign a new empty object if variable is undefined? Commented Aug 5, 2014 at 17:53
  • 5
    There is a difference between undefined and undeclared. As soon as you use var, foo becomes declared as undefined. Commented Aug 5, 2014 at 17:54
  • 1
    This reminds me of short-circuiting. Commented Aug 5, 2014 at 17:55

3 Answers 3

4

There is a difference between undefined and undeclared.

As soon as you use var foo on the left, foo becomes declared as undefined. In the latter example, bar is undeclared and can't be accessed by the expression on the right.


Here are some nifty examples to demonstrate:

var foo = (foo===undefined); // foo is now `true`!
var x = x++;                 // x is now `NaN` (the result of `undefined`+1)
var z = v, v = 1;            // z is actually `undefined` here since the "lefts"
                             //   are all declared before the "rights".

Note: You can't do this with globals that don't use var (eg: x=x++).


Here's a fun blog post about undeclared vs undefined. And, for more thrills, here's an SO post that explains how to test whether a variable is declared or not.

Sign up to request clarification or add additional context in comments.

Comments

1

Although I can't specifically answer why the second doesn't work, I can attempt to answer why the first does work. Through variable hoisting the JavaScript interpretor changes the first one to look like this

var foo;
foo = foo || {};

so it works and the second doesn't because by the time it runs the second line, foo is declared as undefined.

Comments

1

The issue here is the declaration of the variable. If you think about how this is evaluated var will be declared for foo before anything else is evaluated. bar is essentially pointing to something the namespace is completely unaware of.

Once you declare var foo the namespace is aware of the variable regardless of the actual value. In this way without var the namespace tries to look for a built in function or some other non variable definition.

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.