Scoping of variables
JavaScript is a single threaded language that means single context will be created of a particular piece of code(variable, function, code block).
var a = 100;
function outer(){
var a = 20;
var b = 40;
console.log('outer ', a);
}
outer();
On running the above code, instead of calling a = 100, a = 20 will be called. This is because on calling the outer() function, the context of a is created as per the content of outer() . Hence JavaScript does not care what will be the value of a
outside the outer()
while executing.
Calling function inside a function
What can happen if we call a function while we are inside another function, what will be the value of the output variables?
var a = 100;
function outer(){
var a = 20;
var b = 40;
function inner(){
var a = 60;
var b = 30;
console.log('inner b ', b, 'inner a ', a);
}
inner();
console.log('outer ', a);
}
outer();
The console will show the following results
inner b 30 inner a 60
outer 20
This happened because of the same reason that we mentioned in the previous section. The scope of variable when we call inner() shifts to the code block inside of inner() function.
In the absence of a and b declared inside inner() we will get the value of what is declared in outer() function
var a = 100;
function outer(){
var a = 20;
var b = 40;
function inner(){
// var a = 60;
// var b = 30;
console.log('inner b ', b, 'inner a ', a);
}
inner();
console.log('outer ', a);
}
outer();
The console will show the following result
inner b 40 inner a 20
outer 20
The same will happen for the a =20 value. If we don't declare 'a' inside the outer and inner function, JavaScript will look outside the function and if it finds any variable 'a' that is declared globally, it will take that value of 'a'.
Calling inner function directly
We have the following code written for us
function outer(){
var a = 20;
var b = 40;
function inner(){
var a = 60;
var b = 30;
console.log('inner b ', b, 'inner a ', a);
}
inner();
console.log('outer ', a);
}
inner()
inner() is declared inside the outer() function.
We have seen in previous section that outer() can call the inner() function.
What should we expect if we directly call the inner function?
This will throw an error as JavaScript cannot find any function named inner
ReferenceError: inner is not defined
So does this mean it is useless to call any function declared inside any function directly from outside?
Actually this provides some sort of security and shielding to our code as our functions that are implemented within an function is ' hidden ' from outside.
This concept of declaring functions within functions to perform certain tasks is called closures. It allows us to associate data with the lexical environnement in which we are operating, this is similar to object-oriented programming.
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). as per the MDN docs
Prior to classes JavaScript didn't had a method to declare private methods but it became possible to emulate private methods using closures.