Since I am a JavaScript newbie, I started learning it but I got stuck just at the beginning. I am following a Mozilla Tutorial and I have a problem with variable scope in JavaScript. I have some code:
var myvar = "my value";
var zmienna = "string";
(function () {
alert(myvar);
alert(zmienna);
})();
(function () {
alert(myvar); // undefined
var myvar = "local value";
alert(zmienna);
})();
In the tutorial, I've read that JavaScript variables are not visible from function blocks. Well, first two alerts says correct values. It's strange then, because third alert says "undefined", despite fact that nothing has changed from previous function block. The fourth one, again, prints right value.
Could anybody explain me, what is happening here? I would be very glad, because tutorial says nothing more about that.
-
"I've read that JavaScript variables are not visible from function blocks." Where is that in the tutorial? That sentence just does not make sense.Matt Ball– Matt Ball2011年08月26日 15:40:05 +00:00Commented Aug 26, 2011 at 15:40
2 Answers 2
The use of var is hoisted.
Since you have var myvar inside the function, there is a locally scoped myvar. Since you assign a value to it after you alert it, it is undefined when you alert it.
5 Comments
myvar and zmienna declared in global scope. So they are accessible from anywhere in your script, if not hidden by local scope definitions.var inside your function the value will be that of the global variable, which in your example would be the first var myvar = "my value" (line 1). Because you've used the keyword var in your second function (line 13), the value is undefined at the alert (line 12) because var myvar; will be "hoisted" to the top of the function . See Example 2 of the tutorial linked to in your question."I've read that JavaScript variables are not visible from function blocks."
That's not quite right. They are available from the nested functions.
Nested functions create a scope chain. A function created inside another function has access to its own variables as well as the variables of the function in which it was nested.
But function A can not see the variables of function B if function A was not nested inside function B.
var myvar = "my value"; // <-- global variable, seen by all functions
var zmienna = "string"; // <-- global variable, seen by all functions
(function () {
alert(myvar); // <-- referencing the global variable
alert(zmienna); // <-- referencing the global variable
})();
(function () {
// v--- Declaration of these "local" variables were hoisted to the top...
// var myvar; // <--- ...as though it was here.
// var new_var; // <--- ...as though it was here.
alert(myvar); // undefined (myvar is delcared, but not initialized)
alert(new_var); // undefined (new_var is delcared, but not initialized)
var myvar = "local value"; // <-- assign the value
alert(zmienna); // <-- referencing the global variable
alert(myvar); // <-- referencing the local variable
var new_var = "test"; // <-- another new local variable
// A nested function. It has access to the variables in its scope chain.
(function() {
alert(myvar); // <-- referencing the variable from its parent func
alert(new_var); // <-- referencing the variable from its parent func
})();
})();
/*
Here's a new function. It was not nested inside the previous function, so it
has access to the global variables, and not the locals of the previous func
*/
(function () {
alert(myvar); // <-- referencing the global variable
alert(new_var); // <-- ReferenceError
})();