In the following code:
var greeting = "hi";
function changeGreeting() {
if (greeting == "hi") {
var greeting = "hello";
}
alert(greeting);
}
changeGreeting();
...greeting
is undefined. However if I remove the var
and change changeGreeting()
to this:
function changeGreeting() {
if (greeting == "hi") {
greeting = "hello";
}
alert(greeting);
}
...I get "hello" as expected.
I would never redeclare a variable like this in my code, but why does this happen?
It's very simple: JS hoist the Variable declarations to the top of the current scope, but any operations (including assignments) aren't hoisted (within the same scope, see second case explanation), of course. So your snippet is translated to
By leaving out the var, proceeds to scope scanning (checking for the variable being declared in the global scope).
Sadly, in doing so, the context of the first use of the var is lost (inside a branch), and the assignment is hoisted, too. An implied global is translated to:Thank god this isn't true. I assumed it was, because I tested a couple of things in the console that seemed to corroborate this. In this case @amadan is right: you're using the global variable (called
greeting
in your snippet by mistake when I posted this). I'm going to leave the code below (corrected it) to show what implied globals actually are, hoping it helps somebody sometime in understanding scopes/scope-scanning in JS.JavaScript variables have function scope. Thus, the very presence of
var greeting
inside the function will declare a localgreeting
variable, which will be undefined at the time of its mention inif
condition: the global variable will not be visible inside the function, being overshadowed by the local one. Therefore, theif
does not happen, the assignment tohello
doesn't happen, the variable is still undefined.In the second example, you're using the global variable throughout, it is not overshadowed by a local variable (because, no
var greeting
inside the function), and things work as you expect.In your first code snippet, you're checking global variable, which doesn't exist -> doesn't pass if condition.
Check out this on javascript scopes and how to work with variables Javascript garden - function scopes