Demystifying JavaScript: Scopes, Hoisting, and Arrow Functions Explained Simply
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:
varHoisting: JavaScript moves the variable to the top but gives it a temporary placeholder value ofundefined. If you try to print it before you define it, your code won't crash; it will just sayundefined.letandconstHoisting: 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 aReferenceErrorand 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 initializationconst 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
thisdepends on who called the function. If an object calls it,thisrefers to that object. - Arrow Functions: Arrow functions don’t have their own
this. They inheritthisfrom 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: 20In 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!







