3

I want to define a variable to default value if not already defined but found a strange issue.

var x = x || {} works whereas x = x || {} gives an error.

Output from firebug.

>>> a = a || {};
ReferenceError: a is not defined
[Break On This Error]   
a = a || {};
with(_... {}; }; (line 2)
>>> var b = b || {};
undefined

>>> b;
Object {}
>>> a;
ReferenceError: a is not defined
[Break On This Error]   

why does the first one give error while the second seems to go through.

Adi
  • 5,089
  • 6
  • 33
  • 47
vaibhav
  • 127
  • 4
  • 1
    duplicate of http://stackoverflow.com/questions/1470488/difference-between-using-var-and-not-using-var-in-javascript? – Senthil Kumar Aug 12 '12 at 16:56
  • this answer will help you http://stackoverflow.com/a/1470494/205585 – Senthil Kumar Aug 12 '12 at 16:56
  • 1
    There are real duplicates on this, those aren't one of them. – Esailija Aug 12 '12 at 17:00
  • Due to [variable hoisting](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/var#var_hoisting), the definition of `b` is hoisted to the top of the scope so that `b` is defined as a local variable before the assignment operation takes place. The same does not happen for `a`, because it is not defined with `var`. – apsillers Aug 12 '12 at 17:00
  • Demonstration of hoisting (@apsillers): http://jsfiddle.net/meM9P/ Notice `z` is never defined, but `zz` while later defined, returns the `uh oh zz` on that check. – Jared Farrish Aug 12 '12 at 17:04

1 Answers1

0

Just use var. Except for a bug on old IE versions, adding the var saves you an error message and makes it clear that you're not assuming it is declared elsewhere.

On those old versions of IE,

x = (typeof x !== 'undefined' && x) || {}

a typeof check prevents the "undeclared variable" error.

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • 3
    If you are going for old IE, then it's not going to work for this bug http://jsfiddle.net/NBg7j/ (Gives error in IE8 compatibility mode) – Esailija Aug 12 '12 at 17:02
  • @Esailija, good point. I was assuming there was a `var` somewhere and the IE bug I was talking about causes re-initialization to `undefined` when there are `var`s in two ` – Mike Samuel Aug 12 '12 at 17:13
  • Won't the first return `true` to `x`? – Jared Farrish Aug 12 '12 at 17:19
  • @JaredFarrish, no. `(a && b)` returns `b` when `a` is truthy or `a` otherwise. `(a || b)` returns `b` when `a` is falsey or `a` otherwise. – Mike Samuel Aug 12 '12 at 20:59
  • @Jared, In case you're interested, the semantics are defined at http://es5.github.com/#x11.11 – Mike Samuel Aug 12 '12 at 21:56
  • In retrospect, I think I knew that in the back of my mind (sorta), just interesting to see it in action more or less. I'd seen the `x || y` syntax before, I just didn't translate that over to the other operators and how they would work. Thanks for the link. – Jared Farrish Aug 12 '12 at 22:00