22

Here is something interesting I found while learning scope in javascript.

Code

var foo = "This is a global variable.";

var bar = function() {
    alert(foo);
    foo = "Value has been modified";
}

bar();
alert(foo);

This gives the normal response you think you would get, but if I change this one line:

from:

foo = "Value has been modified";

to:

var foo = "Value has been modified";

I get a value of undefined for foo, why is this? Since the function is global scope how come it doesn't accept the var keyword in front of it?

Edit

Now I understand basically what is happening the var foo in the function bar will gain most importance because of the var keyword and get hoisted up, but it will be hoisted up without the value it has been assigned.

5

3 Answers 3

15

In a var statement, there are two parts to it - the actual declaration:

var foo //;

... and the assignment, which is optional:

= 1234567890;

If there is no assignment done to it, the variable (if not already defined) defaults to undefined.


The variable declaration part is moved to the top of the current scope (the start of the function), but not the actual assignment (so it's equivalent to the following):

var foo = "This is a global variable.";

var bar = function() {
    var foo; // undefined
    alert(foo); // yes, it's undefined
    foo = "Value has been modified"; // modify local, not global
}

bar();
alert(foo); // the global one

Functions create their own scope - for example take this:

var test = function ()
{   var bar = 1;
    console.log(bar); // 1
};
test();
console.log(bar); // ReferenceError: bar is not defined
Sign up to request clarification or add additional context in comments.

8 Comments

but if they are hoisted to the top of the current scope, why doesn't it display the value it was assigned?
@htmltroll: because the actual assignment is not hoisted, only the definition.
when you say modify local, not global what do you mean? Doesn't foo modify the global starting variable foo? Because the function is in global scope.
I dislike the term "hoisting". It infers that the whole statement is "moved to the top of the scope" (i.e. execution context). What ECMA-262 says is that variable declarations are processed first, then statements and expressions are evaluated. Hence declared variable exist before they are assigned a value, even if an initialiser is used.
@htmltroll: the content of the function is in another scope - the "Value has been modified" only changes foo while inside the function.
|
4

By using var, you're telling the engine to use a local variable named foo, shadowing the global one.

The reason you get undefined on the alert, is that using var affects the whole scope, not just from that point onwards. You could've written:

var foo;
alert(foo);
foo = "Value has been modified";

Comments

4

The JavaScript engine will parse your code and move var declarations to the top of its scope, but your string assignement to it will stay where it was. After the parse, here is how your code is interpreted:

var foo = "This is a global variable.";    

var bar = function() {
    var foo;
    alert(foo);
    foo = "Value has been modified";
}    

bar();
alert(foo);

As it creates a local variable without any value yet at the top of your function, your alert will show undefined.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.