Introduction
JavaScript is by far the most important programming language when it comes to use cases. We use it in web, mobile and even desktop applications. So, the demand of JavaScript developers is going to be high only. So it is more important to understand the fundamental nuances of the language underneath. How it works? How is it different from other programming languages? And much more...
This much preparation is necessary to tackle down any interview related to JavaScript.
In this blog, I will be covering mainly four topics indepth, that somehow require a separate blog each but I will be keeping it much concise so you can go through all the important concepts in one go.
The topics of discussion in the blog are:
- Scopes
- Single Threaded Nature of JavaScript
- Callstack
- Hoisting
So, without wasting any time, let's begin😃
Scopes
If I have to list one thing that is super important in JS, it would be Scopes.
Why scopes? Because it builds the foundation of the many more features. Without properly understanding this, no one can become a good JavaScript developer, that is for sure.
So, what is scope anyway?
As per MDN,
"The scope is the current context of execution in which values and expressions are "visible" or can be referenced."
I understand that above definition is not quite understandable in the first go. Let me put it in simple words, "it defines the area in which the JavaScript program will look for variables and expressions."
There are four types of scopes in JavaScript:
- Global Scope
- Function Scope
- Block Scope
- Module Scope
Module scope is something that requires another blog in itself that we can do in future.
Our main focus should be on above three scopes, that are, global, function and block scope.
So see, scope defines a program to where look for its variables. Let us understand the scenario from an illustration.
The access to the variable is limited to its own particular scope and in its parent scope with scope chaining.
Global Scope
is the scope in which the variables declared are accessible to all other scopes. It is the "ultimate parent scope".Function Scope
is the scope in which the variables declared are accessible within that particular "function" scope, not outside.Block Scope
is the scope created by a pair of curly braces "{}". Like function scope, it can access outer scope variables.
To understand this, see the following code example:
let myName = "Raushan";
function printName(){
let age = 19;
return `my name is ${myName}` //can access 'myName' variable declared outside function scope
}
console.log(printName());
//accessing age inside the function
console.log(age); //Error: Reference Error
Variable myName
is declared in global scope, so any other scope can access it. Like the function printName()
created its own "function" scope, can access the myName
variable. But variable age
cannot be accessed outside the function scope, it will throw a reference error.
Single Threaded Nature of JavaScript
By definition, JavaScript is a single threaded synchronous programming language.
But what does we mean by "single threaded" ?
Let us dig deeper into it.
Single-threaded means that the JavaScript engine has only one call stack
and whatever context that is at the top of the stack runs first.
So only one statement is executed at a time in the language.
Wait, wait, what is a **call stack**
by the way?
Well, call stack
is nothing but a stack data-structure that keeps the record of the execution contexts or simply what to run first in the JS engine. I understand, this is not making much sense but wait for a minute, I will be explicitily explaining this below in details.
Now coming back to the "Single Threaded" nature of JavaScript, we understood that as the language engine has only single call stack so it cannot run multiple programming statements at a single time. It will wait for the first statement to get executed completely and then execute the second and so forth.
As it is single threaded, JS becomes synchronous
by default. But that does not mean that it is not a non-blocking programming language. It can perform asynchronous programming with the help of Event Loop .
Call Stack
We briefly discussed about call stack
in the above segment. Let's discuss in details here.
As discussed earlier, it is nothing but a stack
data structure that follows LIFO principle - Last In, First Out. In JavaScript, call stack
is actually a mechanism by which the JS interpreter keeps the track of what functions are currently being run and from where the functions are being called, like from inside a function or global scope, etc.
Let us see how exactly the call stack
is populated with functions and how they are emptied:
- Whenever the interpreter encounters a function in the program, it adds the context of the function into the
call stack
and then carries out the function. - If another function is called by that particular function, then it is added on top of the function context in the call stack and then carried out.
- When the function execution completes, it is popped out from the call stack.
Observe carefully below code illustration:
function parentFunc(){
return childFunc();
}
function childFunc(){
return thirdFunc();
}
function thirdFunc(){
return "this is coming from the call stack"
}
console.log(parentFunc()); // prints "this is coming from the Call Stack"
Now see, what exactly is happening in the call stack.
- First of all, function
parentFunc()
is encountered and pushed into the call stack. - As the function is returning another function
childFunc()
, so it is pushed on top of theparentFunc()
in the call stack. - In return, the
childFunc()
is returning yet another functionthirdFunc()
, so it will be pushed on top of thechildFunc()
. - Now, in our call stack, we have three function context one top of another.
thirdFunc()
since, is not returning another function, no execution context will be created on top of it. As it returns something, after returning tochildFunc()
, its context will be popped out.- The context of the
childFunc()
pops out after returning the result to theparentFunc()
. - When
parentFunc()
gets executed, its context also destroys. - In last, as the program ends executing, the
Global Execution Context
also pops out of the call stack leaving it empty.
The call stack for the above program would look like this:
Hoisting
Hoisting is a concept that allows to use functions and variable declaration even before they are declared. It is mostly useful with functions and it is advised to not use them with variable as they may produce reference errors
in some cases.
Well, how it works?
See, in simple words, the interpretor firsts scans through the whole program and allocate memory to the variables and functions. In case, variables are declared with var
keyword, then they are initialised with undefined
value and unintialised otherwise. With functions, whole function code block is stored in the memory unlike variables. After scanning of the program is done, then the execution begins line by line and the variables are assigned their real values and functions are executed.
- Functional Hoisting:
As discussed above, the major advantage of
hoisting
is with functions. We can use a function even before its declaration. As the function code is saved in the memory space in the initial phase of scanning itself, so while code execution, it executes even before its declaration in the program. See the below illustration:
add5(10); // 15
function add5(n){
console.log(`${5+n}`)
}
In the code, we are using the function add5
before declaring it.
Remember that function expression are not hoisted with the whole declaration.
What happens actually is that the function expression is stored in a variable var func = function(){...}
ultimately behaves like a variable.
- Variable Hoisting:
With variables, the declarations are hoisted not the initializations. If the variable is declared with
var
keyword, it will be result intoundefined
in case of hoisting but with other keywords likelet
andconst
, the case is different. An exception will be thrown if a variable declared withlet
orconst
is read before it is initialized.
Conclusion
I heartily thank you for reading this blog. I know this alone is not enough for your preparation and I will advocate the same. The only to master JavaScript is to write JavaScript.
For reading more, I would recommend you to follow :
#iwritecode #lco #javascript