Foundation of JS : Scopes, Hoisting and Closures

Amit GuptaAmit Gupta
3 min read

JavaScript is a powerful programming language, which is used widely in industries. JS has many libraries, both internal and external, which give the developer a lot of flexibility. JS is a single-threaded, synchronous language.

JavaScript is powerful but nuanced, and three concepts—Scopes, Hoisting, and Closures—are essential for writing clean, bug-free code. These concepts affect how variables are declared, accessed, and remembered during execution

Scopes

Scope determines the accessibility or visibility of variables in different parts of your code. JavaScript has:

There are 3 types of scopes in JS:-

  • Block Scope

  • Function Scope

  • Global Scope

Block Scope

Assigning values using let and const: Here, a and b are declared inside the scope, so they can't be accessed outside the scope.

{
  let a = 10;
  const b = 20;
}
console.log(a); // ❌ ReferenceError

Function Scope

Here, a and b are declared inside the function, so they can't be accessed outside the function.

function add(){
    let a = 5;
    const b = 2;
    var answer = a + b;
}
add();
console.log(answer) //❌ ReferenceError

Global Scope

Accessible everywhere

var x = 100;
console.log(x); // 100

Hoisting

When a variable is declared with var or a function, it is moved to the top before the code runs. This is the default behaviour of JS.

  • var is hoisted (and initialized with undefined)

console.log(a); // undefined
var a = 5;
  • let and const are hoisted too, but stay in the "Temporal Dead Zone"

      console.log(b); // ❌ ReferenceError
      let b = 10;
    
  • Function Declarations are fully hoisted

      greeting(); // ✅ Works
    
      function greeting() {
        console.log("Hello!");
      }
    
  • Function Expressions are not hoisted

    
      sayHi(); // ❌ TypeError
      var sayHi = function() {
        console.log("Hi!");
      }
    

Closures

A function can remember the variables from where it was created, even if it's used somewhere else later.

function outer() {
  let score = 0; // this is the power-up

  function inner() {
    score++;
    console.log("Your score is:", score);
  }

  return inner;
}

const play = outer(); // outer runs once and gives back 'inner'
play(); // Your score is: 1
play(); // Your score is: 2
play(); // Your score is: 3
  • The outer function creates a score and an inner function.

  • The inner the function can still use score even after outer is finished.

  • This is a closureinner “remembers” the variable score.


Conclusion

Understanding Scopes, Hoisting, and Closures provides a deeper insight into how JavaScript really works behind the scenes. Mastering these concepts will make your code more predictable, modular, and free of bugs.

0
Subscribe to my newsletter

Read articles from Amit Gupta directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Amit Gupta
Amit Gupta