Why a variable defined global is undefined? [duplicate]
Asked Answered
G

3

34

I have here a simple function and a global variable.

Why is myname undefined and not the string "global"?

var myname = "global"; // global variable
function func() {
    alert(myname); // "undefined"
    var myname = "local";
    alert(myname); // "local"
}
func();

Is not possible to refer to a outer variable that is define outside the scope of that function? And in this a global variable...

And how I can fix this so I don't get a undefined from a global variable?

Geraldgeralda answered 26/5, 2015 at 22:5 Comment(7)
I guess, you forgot 'var' on the global variableKeane
I believe @Keane is correct. Can you post your error message to confirm?Currish
@Keane - i believe you dont know what youre talking aboutPiperpiperaceous
"var" is not needed, and if omitted it will attach to window , creating a global variable , just like OP wantedPiperpiperaceous
A "var" on globals is optional, thought not good practice.Tatman
your question is all messed up. I assume "glabol" is "global"m and "global" is "local".... ?Gauze
Oh! I totally forgot. That was my debugging instinct talking. I am sorry about that.Keane
G
75

You have just stumbled on a js "feature" called hoisting

var myname = "global"; // global variable
function func() {
    alert(myname); // "undefined"
    var myname = "local";
    alert(myname); // "local"
}
func();

In this code when you define func the compiler looks at the function body. It sees that you are declaring a variable called myname.

Javascript Hoists variable and function declarations, by moving the declaration to the top of the function.

Because of hoisting your code is rewritten to the following.

var myname = "global"; // global variable
function func() {
   var myname; //declare local variable and assign it undefined
   alert(myname); // "undefined"
   myname = "local"; // assign local var myname to "local"
   alert(myname); // "local"
}
func();

This "Covers" the global variable. If you want access to the global variable within the scope of a function use the this keyword.

var myname = "global"; // global variable
function func() {
    var myname = "local";
    alert(this.myname); // "global"
    alert(myname); // "local"
}
func();

Note that this only works in calling a function not a method or constructor because the this keyword changes what its bound to based on how you call a function.

EDIT: For completeness

If you want to get access to global variables in any context regardless of function type then declare a global variable that by convention you never cover.

var global = this; // in global scope.
var myname = "global";
var obj = {f: function () {
    var myname = "local";
    console.log(global.myname);
}};
obj.f(); // "global"

Note that this is in method position and the this keyword refers to obj directly and therefore doesn't have myname defined.

Garrulity answered 26/5, 2015 at 22:12 Comment(7)
this is the correct answer , I was mistakenPiperpiperaceous
Thanks for the explanation. It makes sense. I have one question though. Why the declaration was separated from the assignment in the 3rd line of the function?Portillo
@codingpuss hoisting doesn't move where the assignment happens. It only makes a copy of what variables are needed in the function and declares them at the top.Garrulity
If this is in the browser, you can use the window variable instead of your global variable.Ommatophore
Wow, this is extremely bad language design. Unexpectedly shadowing variables without telling the user. How anyone can stand this language is just beyond me.Crabtree
@Crabtree JS was designed in a week. I think it's pretty good considering that.Garrulity
@Garrulity I have heard that as well and some other sources told me it's not true. But that's not the main point. I do not consider this a valid excuse. JS is now a lot older than a week, they had LOTS of time to fix things like this, which are bad beyong imagination. Another reason why this is not a valid excuse is that probably it was not supposed to be let out after only a week of work. Imagine a car designer saying "we designed it in a week, so given that, it's ok, that it barely starts".Crabtree
D
3

Inside a function, you're declaring var myname = "local". Even though you're doing it in the middle of the method, that variable has function scope, so it belongs to the entire function, even the code above it.

So the local variable's value is undefined before that line, and has a value after, but neither one are touching the global variable.

Dowse answered 26/5, 2015 at 22:12 Comment(2)
I don't think this part of your answer is precise: "So the local variable's value is undefined before that line...". The var statement is moved to the top in javascript (hoisting) so it was execute before any other code within its score (in this case, the function)Portillo
As a new programmer, I could not figure out the solution to this issue, no matter how many of these answers I read. The issue is that I assumed every time I wanted to modify a variable I had to start the line with var (like var myVariable = 1;, var myVariable = myVariable + 3;), when in reality, you should only put var the first time you initialize a variable. All other times after that, you need to just start the line with the variable name and drop the var (like var myVariable = 1;, myVariable = myVariable + 3;). (otherwise issues like this question arise)Ieper
G
0

The reason the first alert is undefined is because you re-declared global as a local variable below it in the function. And in javascript that means from the top of the function it is considered the local variable.

The one below it works because just above the alert you gave it a value.

Gauze answered 26/5, 2015 at 22:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.