4

I have a global variable i which I increment (see fiddle here):

(function increment() {
   i += 1;   
})();

i = 0;

​In Chrome, I get the error Uncaught ReferenceError: i is not defined.

Shouldn't the variable i be hosted here, so that inside the function increment, the variable i is defined as undefined?

hippietrail
  • 15,848
  • 18
  • 99
  • 158
Randomblue
  • 112,777
  • 145
  • 353
  • 547

1 Answers1

7

Variable declaration statements are hoisted. You have no declaration.

A declaration statement uses var to declare the variable. Since you haven't declared it, all you have is the assignment expression, which implicitly creates the global variable at the time of the expression evaluation.

In other words, no formal declaration means no hoisting.


Now let's say you did formally declare it, allowing the variable declaration to be hoisted. The operation inside the IIFE would result in NaN, but would be overwritten by the later assignment of 0.

This is because only the declaration is hoisted, not the assignment.

// The 'var i' part below is actually happening up here.

(function increment() {
   i += 1;   // "i" is declared, but not assigned. Result is NaN
})();

var i = 0; // declaration was hoisted, but the assignment still happens here

console.log(i); // 0
I Hate Lazy
  • 47,415
  • 13
  • 86
  • 77
  • Isn't the line `i = 0` a declaration and definition, all in one? – Randomblue Oct 11 '12 at 16:31
  • @Randomblue: It creates it, but it isn't a declaration statement. It's an assignment expression, which implicitly creates the variable at the time of the expression evaluation. – I Hate Lazy Oct 11 '12 at 16:33
  • Doesn't `i=0` create the variable? I think the problem resides in the `i += 1`. It's equivalent to `i = i + i`, and you're trying to use `i` which isn't declared yet. – MalSu Oct 11 '12 at 16:35
  • 1
    @MalSu: It would create it, except that the `i += 1` happens first, so the *ReferenceError* appears before it has a chance. If `var` was used to formally declare the `i` variable, then that declaration would be hoisted to the top of the function *(or global environment)*, and there would be no error even though the declaration came *after* the `i += 1`. – I Hate Lazy Oct 11 '12 at 16:36
  • ...in other words, he knows the `i += 1` is used before the declaration, but is assuming the declaration would be hoisted, preventing the error. And he *would* be correct, except that with no formal declaration, there's no hoisting. – I Hate Lazy Oct 11 '12 at 16:39