1 Answer
1

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

Isn't the line i = 0 a declaration and definition, all in one?
–
RandomblueOct 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 LazyOct 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.
–
MalSuOct 11 '12 at 16:35

@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 LazyOct 11 '12 at 16:36