I just tried to check the scope variation by using the following code, but the result is coming not in an expected way. Can anyone explain what's going on exactly behind this..?
var a = 10;
+ function () {
a = 5;
var a;
alert("inline " + a); //Expected undefined but it displayed as 5
}();
alert(a); //Expected 5 but it alerted 10
DEMO
var hoisting
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 declare
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
The compiler understands your code as
var a;
a = 5;
The position of a var declaration within a function doesn't matter. These are entirely equivalent:
function () {
var a;
a = 5;
}
function () {
a = 5;
var a;
}
when use "var a" you request global value of variable, use "window.a" to display it:
<script>
var a = 10;
+ function () {
a = 5;
var a;
alert("inline " + window.a); //Expected undefined but it displayed as 5
}();
</script>
var a = 10; // Global scope
+ function () {
a = 5; // You are not using Var here .. so it is also a global scope
var a; // Now you are mentioning your a is Var so scope is changed from global to this function
alert("inline " + a); // Printing 5 because you local scope a has value of 5.
}();
alert(a); // Printing 10 because of global scope a has value 10
Related
So if i declare two variables like this:
var a = 5;
var b = 10;
Javascript compiles code and until the assignment occurred these variables are undefined.
But if i write like that:
var a = 5;
var a = 10;
what happens when these variables hoisting?They both have name a and
they are undefined?Or maybe it's one variable and undefined is written twice in it?
Hoisting isn't really relevant here. You can't have two variables with the same name in the same scope. As many times as you write var a, there is just one variable a, which is hoisted no differently than if you had a single var a.
This code...
function() {
var a = 5;
var a = 10;
}
is functionally equivalent to this code, with a hoisted:
function () {
var a;
a = 5;
a = 10;
}
One more JavaScript scoping problem. I believe this is not related to 'hoisting'.
I've a small block of code here - http://jsfiddle.net/0oqLzsec/2/
var c = function(){
var x = 'before',
callBefore = function(){
alert(x);
},
callAfter = function(){
_callAfter();
};
return{
callBefore : callBefore,
callAfter : callAfter
}
var y = 'after';
function _callAfter(){
alert(y);
}
};
var obj = c();
obj.callBefore();
obj.callAfter();
callAfter() always alerts 'undefined' even if the variable y is defined before _callAfter(). But If I move the variable y declaration before variable x it is working.
I'm wondering if callAfter() can _callAfter() which is defined below, why can't it read variable y?
_callAfter and y are both hoisted, which makes them known as local variables through the function invocation. The _callAfter function is able to be called (as you do), and it also closes over the variable y. However, this variable does not get a value assigned before you return from the c function. Thus, you get undefined. It is the same if you put var y; BEFORE the return, and y='after'; after the return.
In other words, the following two are equivalent:
function foo(){
var a;
return function(){ return a };
a = 42; // never runs
}
alert( foo()() );
function bar(){
return function(){ return a };
var a = 42;
}
alert( bar()() );
Here's an example showing that the local variable is hoisted and closed over, even when the function literal occurs before the var in code:
function build() {
return function(newValue) {
alert("was: " + oldValue);
oldValue = newValue;
alert("now: " + oldValue);
}
var oldValue = 42;
}
f = build();
f(17);
// was: undefined
// now: 17
f(99);
// was: 17
// now: 99
It is related to hoisting, var y is moved to the top of the function, but the assignment (y = 'after') is not, so it never runs because it's after the return statement.
The JS engine rewrites your code to look something like:
var c = function(){
// functions also get hoisted to the top
function _callAfter(){
alert(y);
}
var x = 'before',
callBefore = function(){
alert(x);
},
callAfter = function(){
_callAfter();
},
// y declaration is hoisted to the top of the function
y;
return {
callBefore : callBefore,
callAfter : callAfter
};
// the assignment never gets called because it's after the return
y = 'after';
};
This question already has answers here:
Surprised that global variable has undefined value in JavaScript
(6 answers)
Closed 8 years ago.
var a = 2;
var b = function(){
console.log(a);
var a = 1;
};
b();
When I call b, it prints undefined. What is the reason?
Inside a function, var declares a function-scoped variable. That means it's visible to the function. The entire function. That means you are print out the variable before assigning a value to it.
var a = 123;
(function () {
a = 456; // Changes the function's "a"
console.log(a); // Outputs the function's "a": 456
var a; // At compile-time, declares a function variable named "a".
})();
console.log(a); // Outputs the global "a": 123
Along the same line, repeating the declaration doesn't do anything. The following prints out 123.
(function () {
var a = 123;
var a;
console.log(a); // 123
})();
The var a in your code is a variable declaration that declares a variable within the scope of its containing function. Due to variable hoisting, variable declarations (like var a) are hoisted to the top of their containing function. While any declaration is hoisted, assignments to that variable are not hoisted, Thus, your code is equivalent to:
var a = 2;
var b = function(){
var a; // hoisted declaration; declares `a` within this function scope
console.log(a);
a = 1; // not-hoisted assignment
};
b();
Since a declared variable is undefined until it is given a value, this code logs undefined.
You have this:
var a = 2;
var b = function(){
console.log(a);
var a = 1;
};
During the run time it becomes:
var a = 2, b;
b = function(){
var a; // new variable declaration with no value assigned
console.log(a); // You used it new "a" without assigning any value
a = 1;
};
Inside the function the a is a new variable because of var keyword and JS is taking this new a in account which is undefined not the global a. Tow variables with same name, one is outside the function (in global scope) and another is inside the function. Since there is a new variable available inside the function so it's being used in console.log(a) but no value assigned.
You may read JavaScript Scoping and Hoisting and var on MDN.
I tried following code:
var a = 5;
function x() {
console.log(a);
}
x();
It runs as expected and prints 5.
But i changed the code so the global variable a will be overwrite as follows:
var a = 5;
function x() {
console.log(a);
var a = 1;
}
x();
It prints undefined. It doesn't make sense for me since the overwrite should be happened right after console.log(a). So what is the problem?
This is happening because your second a variable is being 'hoisted' to the top of the function and it hides the first a. What is actually happening is this:
var a = 5;
function x() {
var a;
console.log(a);
a = 1;
}
x();
Here is an article on hoisting from adequately good for further reading on the subject.
var a = 5;
function x() {
var a = 1;
console.log(a);
}
x();
you need to initalize variable a before console.log();
var x = 3;
(function (){
console.log('before', x);
var x = 7;
console.log('after', x);
return ;
})();
In the above code var X is initialized globally. So inside the function the first console.log should print "before 3" but i don't get it. The reason is that i am trying to re-declare the global variable.
Can somebody explain why this is happening?
In the above code var X is initialized globally. so inside the function the first console.log should print "before 3".
No, it should print before undefined, because var takes effect from the beginning of the function regardless of where you write it.
Your code is exactly the same as this:
var x = 3;
(function (){
var x;
console.log('before', x);
x = 7;
console.log('after', x);
return ;
})();
And of course, variables start with the value undefined.
Details: Poor misunderstood var
The JavaScript parser does Variable Hoisting when parsing your code. This means that any variable declaration will be moved to the top of the current scope, thus in your case, this code will get executed:
var x = 3;
(function (){
var x;
console.log('before', x);
x = 7;
console.log('after', x);
return ;
})();
So your local variable x gets declared at first with an initial value of undefined.
This should explain, why you get an "beforeundefined" for the first console.log().
The scope of a variable is much simpler than in other languages. It doesn't start at declaration but is either :
the function in which you have the declaration
the global scope if the declaration isn't in a function
MDN :
The scope of a variable declared with var is the enclosing function
or, for variables declared outside a function, the global scope (which
is bound to the global object).
You can imagine that all variable declarations are moved to the start of the scope (the function). So this is exactly like
var x = 3;
(function (){
var x;
console.log('before', x); // now undefined
x = 7;
console.log('after', x); // now 7
return ;
})();
Be careful to understand what is the exact scope (the function, not the block) :
var x = 3;
(function (){
console.log('before', x); // this is undefined !
if (true) {
var x = 7;
}
return ;
})();