Because the scope is function scope, the body of a function establishes new context, but
if, for, switch,
and {},
and anything else that is not a function does not create a new context.So, to demonstrate that with a little code:
//Global scope var i; for(i=0;i<3;i++){ //Still Global scope var myTotal = i; } alert(myTotal); // 2Since the for loop has no affect on the variable scop, all references to myTotal above are in the Global space.
Of course functions do have a local scope, as seen with this snippet:
function newFunction() { //newFunction local scope var myVar = "Original Var"; if (true) { myVar = "New Var";//newFunction local scope } alert(myVar); // "New Var"; } newFunction(); alert(myVar) // ReferenceError ThrownThe alert within the function gives "New Var", which is a local variable.
The alert outside of the function throws a ReferenceError because there is no myVar in the Global space, and within the Global space we do not have access to local variables that were declared within a function body.
JavaScript also does something that has been called “hoisting”. JavaScript varable declarations will be moved to the top of their scope. Note, it's just the declarations, not the initialization.
Variable hoisting can lead to some unexpected results, for instance this:
var myVar = "Original Var" function newFunction() { if (!myVar) { var myVar = "New Var"; } alert(myVar); } newFunction(); // "New Var"The value of myVar at the
if
statement is undefined
because the local variable has been declared, but not initialized. The variable declaration is moved to the top of the function, and so is really no different than this:var myVar = "Original Var" function newFunction() { var myVar; if (!myVar) { myVar = "New Var"; } alert(myVar); } newFunction(); // "New Var"That version of the function makes it clear that the myVar is declared at the top of the scope, and that it is at that point uninitialized. It also makes clear that the
if
statement is extraneous by clearing up what is happening with the local variable. Moving your variable declarations to the top is a JavaScript “Best Practice” because it turns the code into a more accurate expression of what JavaScript is actually going to do.
Thanks Paul, awesome post.
ReplyDeleteI found this page on hoisting very helpful as well:
http://www.programmerinterview.com/index.php/javascript/javascript-hoisting/