Sitemap
RoccoMax

RoccoMax

Navigating where logic meets life—from coding & entrepreneurship to biology, geopolitics, geography, travel, interesting facts, and modern love.

Press enter or click to view image in full size
Photo by Rahul Mishra on Unsplash

Demystifying JavaScript: Scopes, Hoisting, and Arrow Functions Explained Simply

4 min readOct 1, 2026

--

If you are learning JavaScript, you have probably run into code that behaves completely differently than you expected. Variables appear out of nowhere, functions crash before they run, and the this keyword seems to have a mind of its own.

Don’t worry — you aren’t alone. Today, we are going back to basics to clear up the most common JavaScript confusions: variable scopes, the magic of hoisting, and how different functions actually work.

1. Block Scope: Why let and const fixed var

In JavaScript, a “block” is any code wrapped in curly braces { }, like an if statement or a for loop.

When you create a variable using let or const, it is block-scoped. This means it is strictly trapped inside those curly braces. Once the code finishes running that specific block, the variable vanishes.

But var is a rebel. It is function-scoped, meaning it ignores block boundaries entirely. If you declare a var inside an if block, it "leaks" out and can be accessed anywhere else within that same function.

Let’s look at this in practice:

JavaScript

function checkScope() {
if (true) {
var oldWay = "I escape the block!";
let newWay = "I am trapped in the block!";
}
  console.log(oldWay); // Works! Outputs "I escape the block!"
console.log(newWay); // Fails! ReferenceError: newWay is not defined
}The Takeaway: Always use let and const. They keep your variables predictable and prevent accidental bugs caused by leaking data.

2. Hoisting: JavaScript’s Invisible Scanner

Hoisting sounds complicated, but it is just JavaScript doing a bit of prep work. Before your code runs line-by-line, JavaScript scans it and moves all variable and function declarations to the top of the memory.

However, var and let/const behave very differently during this process:

  • var Hoisting: JavaScript moves the variable to the top but gives it a temporary placeholder value of undefined. If you try to print it before you define it, your code won't crash; it will just say undefined.
  • let and const Hoisting: JavaScript knows they exist, but it refuses to give them a placeholder. They are placed in a locked zone called the Temporal Dead Zone (TDZ). If you try to touch them before their actual line of code runs, JavaScript throws a ReferenceError and crashes.

JavaScript

// Using var
console.log(myVar); // Output: undefined
var myVar = "Rahul";
// Using let
console.log(myLet); // Output: ReferenceError!
let myLet = 25;

3. Function Hoisting: Can I call a function before I make it?

Yes, but it depends on how you made it.

Normal Functions (Function Declarations)

If you build a function using the standard function keyword, JavaScript hoists the entire function body to the top. You can safely call it before you write it.

Get RoccoMax’s stories in your inbox

Join Medium for free to get updates from this writer.

JavaScript

sayHello(); // Output: "Namaste!"
function sayHello() {
console.log("Namaste!");
}

Function Expressions & Arrow Functions

If you save a function inside a variable (let, const, or var), it follows the hoisting rules of variables, not functions. You cannot call them before you define them.

JavaScript

shout(); // ReferenceError: Cannot access 'shout' before initialization
const shout = () => {
console.log("HEY!");
};

4. Arrow Functions vs. Normal Functions

Arrow functions (=>) aren't just a shorter way to write functions. They behave fundamentally differently from normal functions, especially when it comes to the this keyword.

  • Normal Functions: The value of this depends on who called the function. If an object calls it, this refers to that object.
  • Arrow Functions: Arrow functions don’t have their own this. They inherit this from the surrounding environment where they were written.

JavaScript

const user = {
name: "Rahul",

// Normal Function
normalCall: function() {
console.log("Normal:", this.name); // Output: "Normal: Rahul"
},
  // Arrow Function
arrowCall: () => {
console.log("Arrow:", this.name); // Output: "Arrow: undefined"
}
};
user.normalCall();
user.arrowCall();

Rule of thumb: Never use arrow functions as object methods!

5. Anonymous Functions: How do you call a function with no name?

You might have noticed code where a function has no name at all. This is called an Anonymous Function.

If a function has no name, how do you call it? The trick is to save it inside a variable. The variable’s name becomes the function’s identity.

JavaScript

// We created a function with no name and stored it in 'doWork'
const doWork = function() {
console.log("I am doing my work!");
};
// We call the function using the variable's name
doWork();

This is exactly how Arrow Functions work, too. They are inherently nameless, which is why we always store them in variables:

JavaScript

const multiply = (a, b) => {
return a * b;
};
console.log(multiply(5, 4)); // Output: 20

In JavaScript, functions are treated just like any other value (like a string or a number). You can store them in variables, pass them into other functions, and return them. Once you understand that, JavaScript starts to make a whole lot more sense!

--

--

RoccoMax

Written by RoccoMax

0 followers

Navigating where logic meets life—from coding & entrepreneurship to biology, geopolitics, geography, travel, interesting facts, and modern love.