In this article, we'll cover a few intermediate level JS interview questions [1.Scope 2.single thread 3.call stack 4.hoisting.]that will help you to crack your next JS interview.
Scope
The accessibility or visibility of variables in JavaScript is referred to as scope. That is, which sections of the program can access a given variable and where the variable can be seen. There are usually three types of scopes:
Global Scope
The global scope includes any variable that is not contained within a function or block (a pair of curly braces). Global scope variables can be accessed from anywhere in the program. An example showing the global scope of a variable is given below:
var hello = 'Hello!';
function sayHello() {
console.log(hello);
}
// 'Hello!' gets logged
sayHello();
Local or Function Scope
Variables declared inside a function are local variables. They can only be accessed from within that function; they are not accessible from outside code. An example showing local scope of a variable is given below:
function sayHello() {
var hello = 'Hello!';
console.log(hello);
}
// 'Hello!' gets logged
sayHello();
console.log(hello); // Uncaught ReferenceError: hello is not defined
Block Scope
Unlike var variables, let and const variables can be scoped to the nearest pair of curly brackets in ES6. They can't be reached from outside that pair of curly braces, which means they can't be accessed from the outside. An example showing the block scope of a variable is given below:
{
let hello = 'Hello!';
var language = 'Hindi';
console.log(hello); // 'Hello!' gets logged
}
console.log(language); // 'Hindi!' gets logged
console.log(hello); // Uncaught ReferenceError: hello is not defined
JavaScript Hoisting
Prior to executing the code, the interpreter appears to relocate the declarations of functions, variables, and classes to the top of their scope using a process known as Hoisting in JavaScript. Functions can be securely utilized in code before they have been declared thanks to hoisting. Variable and class declarations are likewise hoisted, allowing them to be referenced prior to declaration. It should be noted that doing so can result in unforeseen mistakes and is not recommended. There are usually two types of Hoisting:
Function Hoisting
Hoisting has the advantage of allowing you to use a function before declaring it in your code as shown in the code snippet given below. Without function hoisting, we would have to first write down the function display and only then can we call it.
display("Lion");
function display(inputString) {
console.log(inputString); // 'Lion' gets logged
}
Variable Hoisting
You can use a variable in code before it is defined and/or initialised because hoisting works with variables as well. JavaScript, however, only hoists declarations, not initializations! Even if the variable was initially initialised then defined, or declared and initialised on the same line, initialization does not occur until the associated line of code is run. The variable has its default initialization till that point in the execution is reached (undefined for a variable declared using var, otherwise uninitialized). An example of variable hoisting is shown below:
console.log(x) // 'undefined' is logged from hoisted var declaration (instead of 7)
var x // Declaration of variable x
x = 7; // Initialization of variable x to a value 7
console.log(x); // 7 is logged post the line with initialization's execution.
Single Thread
A single-thread language is one with a single call stack and a single memory heap. It means that it runs only one thing at a time.
A stack
is a continuous region of memory, allocating local context for each executed function.
A heap
is a much larger region, storing everything allocated dynamically.
A call stack
is a data structure which basically records where we are in the program.
Call Stack
Let's write a simple code and track what's happening on the call stack.
As you can see, the functions are added to the stack, executed and later deleted. It's the so-called LIFO way - Last In, First Out. Each entry in the call stack is called a stack frame.
Knowledge of the call stack is useful for reading error stack traces. Generally, the exact reason for the error is at the top in first line, though the order of code execution is bottom-up.