Scoping
What is the output of following JavaScript code.
var x = 1;
{
var x = 2;
console.log("Inside: " + x);
}
console.log("Outside: " + x);
If your answer is 2,1 then you must read on.
In JavaScript function is the only thing that creates a new scope.
Lets see an example to understand what this means.
var x = 1;
function y() {
var x = 10;
console.log("Before Exiting y's scope the value of x is : " + x);
}
console.log("Outside y's scope the value of x is : " + x);
y();
Output of this program is
Outside y's scope the value of x is : 1
Before Exiting y's scope the value of x is : 10
The reason is function y() creates its own local scope and any variable in functions scope is local to its scope. Here var x = 10 declaration inside scope of function y() overshadows var x = 1 declaration in global scope.
Lets modify the above example a little bit and see what happens.
- Program 2:
var x = 1;
function y() {
console.log("On Entering y's scope the value of x is : " + x);
console.log("Before Exiting y's scope the value of x is : " + x);
}
console.log("Outside y's scope the value of x is : " + x);
y();
- Program 2 (modified):
var x = 1;
function y() {
console.log("On Entering y's scope the value of x is : " + x);
var x = 10;
console.log("Before Exiting y's scope the value of x is : " + x);
}
console.log("Outside y's scope the value of x is : " + x);
y();
If you expect the result as 1,1,1 and 1,10,1 then you must watch closely.
- Output of Program 1 is : 1,1,1
- Output of Program 2 is : undefined,10,1.
The answer to this subtle question is scoping and variable declaration hoisting.
Hoisting
Variable Declaration Hoisting
Program 2 is internally interpreted as below, declaration of variable x inside will be hoisted to the top of its scope (in our case scope of function y() ). Only declaration is hoisted not the assignment.
On entering function y() scope the program try to access the value of x but by this time only x is declared not assigned, hence JavaScript returns undefined. This is a subtle but important understanding.
- Program 2: Variable Declaration hoisting
var x = 1;
function y() {
var x;
console.log("On Entering y's scope the value of x is : " + x);
x = 10;
console.log("Before Exiting y's scope the value of x is : " + x);
}
console.log("Outside y's scope the value of x is : " + x);
y();
Function Declaration Hoisting
Like variables functions are also hoisted. Hoisted in a sense browser first loads the function declaration before anything else is loaded.
Lets see an example of function declaration hoisting.
- Program 3: Function Declaration hoisting
bar();
function bar() {
console.log('bar called.');
};
Output of this program is : [bar is called]
The reason is as already said function declaration is loaded upfront by the browser before it loads anything else.
Functional Expression hoisting
Lets see another slightly different example.
- Program 4: Functional Expression hoisting
foo();
var foo = function () {
console.log('foo called.');
};
The slight difference between Program 3 and Program 4 is use of functional expression in the later .
Remember only declaration is hoisted not assignment. Hence internally Program 4 is interpreted as.
- Interpreted Program 4: Functional Expression hoisting
var foo;
foo();
foo = function () {
console.log('foo called.');
};
Here foo is only declared not assigned any type at the point where call is made and this call is assumed of type function which is an error, hence TypeError .
Conclusion
- Function is the only thing that creates a new scope in JavaScript.
- Only variable declaration is hoisted to the top of its scope, assignment is not hoisted.
- Function declaration (not functional expression) is loaded first by the browser before it loads anything else.
No comments:
Post a Comment