Why does shadowed variable evaluate to undefined when defined in outside scope? - javascript

Consider the following piece of code:
<html><head></head>
<body>
<script type="text/javascript">
var outside_scope = "outside scope";
function f1() {
alert(outside_scope) ;
}
f1();
</script>
</body>
</html>
The output for this code is that the alert box displays the message "outside
scope". But, if I slightly modify the code as:
<html><head></head>
<body>
<script type="text/javascript">
var outside_scope = "outside scope";
function f1() {
alert(outside_scope) ;
var outside_scope = "inside scope";
}
f1();
</script>
</body>
</html>
the alert box displays the message "undefined". I could have
understood the logic if it displays "undefined" in both the cases. But, that
is not happening. It displays "undefined" only in the second case. Why is this?
Thanks in advance for your help!

Variables are subject to hoisting. This means that regardless of where a variable is placed within a function, it is moved to the top of the scope in which it is defined.
For example:
var outside_scope = "outside scope";
function f1() {
alert(outside_scope) ;
var outside_scope = "inside scope";
}
f1();
Gets interpreted into:
var outside_scope = "outside scope";
function f1() {
var outside_scope; // is undefined
alert(outside_scope) ;
outside_scope = "inside scope";
}
f1();
Because of that, and the function only scope that JavaScript has, is recommended to declare all the variables at the top of the function, to resemble what will happen.

In the first case, your code is accessing the global variable "outside_scope", which has been initialized to "outside scope".
Javascript has function level scope, so in the second case it is accessing the function scoped variable "outside_scope", but it has not yet been initialized at the time of the alert box. So it displays undefined.

JavaScript has function scope, not block scope.
In the second case, the declaration of outside_scope is hoisted up to the top of the function (but the assignment isn't).
This is a great example of why JavaScript code is easier to read if you put all your variable declarations up at the top of the function. Your second example is equivalent to:
function f1() {
var outside_scope;
alert(outside_scope);
outside_scope = "inside scope";
}
and you can probably now understand why you're getting "undefined."

In the second example the local variable exists for the entire function scope. It doesn't matter that you defined it after the alert, it exists for the entire function.
However, the actual assignment doesn't occur until after the alert, hence the "undefined".

This is due to something called the hoisting of variable declarations.
Basically, JavaScript separates a variable declaration in two, leaving the assignment where you did the declaration and hoisting the actual declaration to the top of the function:
var f1 = function () {
// some code
var counter = 0;
// some more code
}
var f2 = function () {
var counter; // initialized with undefined
// some code
counter = 0;
// some more code
}
On run-time, f1() gets translated into f2(). I wrote an in depth blog post about this here. I hope this helps you understand what happens in your code.
This is also the reason, it is recommended to declare your variables at the top of a function in JavaScript. It helps you understand what the code does, when it runs.

that's an interesting case.
in the first example, you have defined a 'global' variable. it has global scope and is therefore accessible in any function/object for the execution.
in the second example, you have 'blocked' the global variable with the function scope variable, but since it hasn't been initialised yet at the time of the alert, it returns 'undefined'.
i agree this isn't the most intuitive quirk, but it does make sense.

Related

Why variables of function declared outside through "." accessible only through "." inside the function?

I initialized a variable of function through "." outside the function. Regarding closure rule, it should be set inside the function scope and after execution should be gone. But
Why after calling the function variable still exists?
Why can I access inside a function only through "."?
I initialized variable outside of the function through "." like f1.a = "any variable".
I checked if the variable of function initialized outside is accessible inside a function without ".":
I tried to get access to the variable inside the function. It seems if I get access to the variable by itself without "." it gives me an error "variable is not defined".
I checked if the variable of function initialized outside will be gone after function execution:
I call function and check if the value of the variable after execution is still available. Yes, it was still there.
f1.a = "any variable";
function f1(){
(function()
{
console.log(a);
}()) // a is not defined
}
f1();
console.log(f1.a); // after f1(), f1.a still exist
I expected variable "a" visible by itself inside the "f1" since I initialized inside the function scope f1.a = "any variable", but I can get access only with "."
I expected variable "a" will be gone after execution f1(), but it still exists
There are several things you need to understand to get a clear idea of what's happening here. First, JavaScript hoists function definitions to the top of the file.
Knowing that, you could imagine your code is something like this once JavaScript interprets it:
var f1 = function (){
(function()
{
console.log(a);
}()) // a is not defined
}
f1.a = "any variable"
f1();
console.log(f1.a);
Secondly, in your first console.log(a) you are referencing a variable a which was never declared. If you change that to console.log(f1.a) you'll see the value of f1.a as expected.
It's also not clear why you are using an immediately invoked function inside of your f1 function. It makes analyzing this code even more complex. It seems like you are trying to get a better understanding of how closures work? But for closures you should be interested in variables declared inside of f1, rather than properties of f1. For example, something like this.
f1 = function (){
var a = 'something'
return function()
{
console.log(a);
}
}
var closure = f1();
// f1 is finished running here.
closure(); // closure still has access to f1's variable.
I think the three areas you could learn more about to understand the code above are 1. Scope and especially hoisting 2. Objects, this and object properties and 3. Closures.

Javascript Function Scope Confusion

Can someone explain this to me:
var test = 5;
// prints 5;
function printMe1(){
console.log(test);
}
// prints "undefined"
function printMe2(){
console.log(test);
var test = 10;
}
Is this because printMe2 creates a local variable of "test"? And if so, why does the log statement refer to the local variable, if it is declared after it?
And also, if JS is an interpreted language, shouldn't the code be interpreted line by line? In which case the log statement shouldn't be able to know that the local "test" variable is declared later?
there is a concept in javascript "hoisting" so in hoisting variables and function declarations are moved to the top of their scope before code execution. remember only declaration, not the definition. that's why in your code var test is showing undefined because you are using this variable before defining it.
var test;
function printme2(){
console.log(test)
test=10
}
printme2()
I just did some googling and found the answer.
It is because Javascript "hoists" variable declarations to the top of the scope. So the local "test" variable was declared at the top of the function scope, thus the reason why printing it gave "undefined".
(if any of this wrong let me know please :) )

Javascript:why the result of the function about alert is undefined

var name="Jim";
var func=function(){
alert(name);
var name=true;
}
func();
var name="Jim";
var func=function(){
alert(name);
name=true;
}
func();
Two function has different results, can someone give me an explaination?
The reason this occurs is from hoisting. The variable declaration inside of your function scope is hoisted to the top. What this means is that your first function actually looks like this
var name="Jim";
var func=function(){
var name;
alert(name);
name=true;
}
func();
Which should make it more clear why undefined is alerted.
See "var hoisting" for a more in depth explanation.
Because variable declarations (and declarations in general) are processed before any code is executed, declaring a variable anywhere in the code is equivalent to declaring it at the top. This also means that a variable can appear to be used before it's declared. This behavior is called "hoisting", as it appears that the variable declaration is moved to the top of the function or global code.
Your first function is equivalent to:
var name="Jim";
var func=function(){
var name;
alert(name);
name=true;
}
func();
because variable declarations are always put by Javascript at the beginning of the scope. Therefore, when alert(name) is executed, name is undefined.
More information about scopes can be found in this answer.

Variable not hoisted

In Javascript variables are hoisted to the top of the scope they are declared within.
However in the following code it seems that the variable myvar is not hoisted.
<html>
<body>
</body>
</html>
<script type="text/javascript">
console.log(typeof myvar);
var myvar = "value";
console.log(typeof myvar);
</script>
The output of the above is:
undefined
string
I expected that the first line would say "string" because myvar is supposed to be hoisted to above it.
Why isn't this so?
Variable declarations are hoisted, the assignments are not.
By using var myvar anywhere in the function you create a locally scoped variable myvar, but if you follow it with = something then the assignment will take place in normal code order.
A dupe of this came up, and Quentin's answer is good (as always), but just to spell it out even more:
The way the JavaScript engine actually processes that code is like this:
// Before any step-by-step code
var myvar;
// Now step-by-step starts
console.log(typeof myvar); // undefined since no value has been written to it
myvar = "value";
console.log(typeof myvar); // "value" because that's its value now
That is, this:
var myvar = "value";
... is actually two separate things that happen at two separate times. The variable declaration (the var myvar part), which happens before any step-by-step code in the scope is run, and the initialization (the myvar = "value" part; it's really an assignment expression by the time it's processed), which happens where that line is in the code.

cannot read a variable from the global context

JS:
var a = 10;
function test() {
alert(a);
var a = 20;
alert(a);
}
test();
The above code was discussed earlier with an interviewer yesterday, i said first time browser would alert 10 and for the next time it would alert 20, but i was wrong. It alerted undefined for the first time and 20 for the second time. I am confused and can anybody theoretically as well as practically explain what's going behind this..?
Relevant link would be very helpful.
DEMO
In a function, every var is treated as if it appeared at the very top of the function. Thus your code is interpreted as if it were written:
function test() {
var a;
alert(a);
a = 20;
alert(a);
}
It's called hoisting. Note that it's the declaration that's hoisted, not the initialization assignment.
The effect here is that everywhere inside that function, a refers to the local variable, which hides the relatively global a from view.
Here is the relevant section of the ES5 spec. It's somewhat opaque.
When your variable is found in the local scope of the function then it doesnt refer to the global variable. The scope of the global variable is hidden inside the function and hence you are getting the undefined value for the first time.
This concept is called Hoisting ie, In JavaScript, a variable can be declared after it has been used. In other words; a variable can be used before it has been declared.

Categories