25 JavaScript Hoisting
25 JavaScript Hoisting
What is Hoisting?
Function Hoisting
As you can see, we've called the sayHello() function before it is defined, but
the code still works. This is because the function declaration is hoisted to the
top automatically behind the scenes.
Variable Hoisting
Similarly, the variable declarations are also hoisted to the top of their current
scope automatically. This means that if the variable is declared inside a
function block, it will be moved at the top of the function, but if it is declared
outside any function it will be moved to top of the script and become globally
available.
str = "Hello World!";
alert(str); // Outputs: Hello World!
var str;
Variable hoisting may seem a little bit confusing at first glance, but if you go
through these examples carefully you will easily understand how it works.
JAVASCRIPT CLOSURES
Understanding the JavaScript Closures
However, there are certain situations when you want a variable to be available
throughout the script, but you don't want just any part of your code to be able
to change its value accidently.
// Global variable
var counter = 0;
// A function dedicated to manipulate the 'counter' variable
function makeCounter() {
return counter += 1;
}
// Calling the function
makeCounter();
console.log(counter); // Prints: 1
makeCounter();
console.log(counter); // Prints: 2
// Trying to manipulate the 'counter' variable from outside
counter = 10;
console.log(counter); // Prints: 10
As you can see in the above example, the value of the counter variable can be
changed from anywhere in the program, without calling
the makeCounter() function.
function makeCounter() {
// Local variable
var counter = 0; // Manipulating the 'counter' variable
return counter += 1;
}
// Calling the function
console .log(makeCounter()); // Prints: 1
console .log(makeCounter()); // Prints: 1
In this case the counter variable cannot be manipulated from outside, since it is
local to makeCounter() function, but its value will also not increase after
subsequent function call, because every time we call the function it reset
the counter variable value, which you can clearly see in the above example (line
no-11). The JavaScript closure can solve our problem.
A closure is basically an inner function that has access to the parent function's
scope, even after the parent function has finished executing. This is
accomplished by creating a function inside another function.
function makeCounter() {
var counter = 0;
// Nested function
function make() {
counter += 1; return counter;
}
return make;
}
/* Execute the makeCounter() function and store the returned
value in the myCounter variable */
var myCounter = makeCounter();
console .log(myCounter()); // Prints: 1
console .log(myCounter()); // Prints: 2