Closures, new, and this in JavaScript
A Comprehensive Guide to Closures, new, and this in JavaScript

I'm a passionate backend dev
Hey there, JavaScript adventurers! Ready to crack open some of the juiciest, brain-bending concepts in JS? Today, we’re tackling closures—those sneaky memory wizards—and the dynamic duo of new and this, which can either be your best friends or your trickiest foes. By the end of this ride, you’ll be wielding these tools like a pro, and your code will be flexing some serious muscle.
Grab a coffee (or a snack, I don’t judge 🧑⚖️), and let’s jump into the fun!
Closures: The Secret Keepers of JavaScript
Imagine closures as little treasure chests that lock away variables and keep them safe, even after the party’s over. They’re what happens when a function “remembers” its scope, long after it’s done running. Sounds wild? Let’s see it in action.
What’s a Closure, Anyway?
A closure happens when an inner function has access to an outer function’s variables—even after the outer function has finished executing. It’s like a backpack that carries its environment wherever it goes.
Here’s a classic example:
function outer() {
let secret = "I’m a ninja!"; // 'secret' is declared in the outer function's scope
function inner() {
console.log(secret); // 'inner' function can access 'secret' from its outer scope
}
return inner; // 'outer' returns the 'inner' function
}
const myFunc = outer(); // 'myFunc' now holds the 'inner' function, along with the closure over 'secret'
myFunc(); // I’m a ninja! // Calling 'myFunc' executes 'inner', which still has access to 'secret'
Whoa, hold up! outer ran and returned inner, but inner still remembers secret. That’s a closure—inner closed over the secret variable, keeping it alive in its little memory bubble.
Let’s Get Practical
Closures aren’t just normal tricks—they’re everywhere. Check out this counter:
function makeCounter() {
let count = 0; // 'count' is initialized in the outer function's scope
return function () { // Returns an anonymous function that forms a closure
count++; // Increments 'count' which is in the closure's scope
console.log(count);
};
}
const counter = makeCounter(); // 'counter' now holds the inner function and its closure
counter(); // 1 // First call increments and logs 'count'
counter(); // 2 // Second call increments the *same* 'count' due to closure
counter(); // 3 // And so on...
Every time you call counter(), it bumps count up. How? The inner function has a closure over count, so it’s not reset—it’s persistent. Mind blown yet?
Real-World Use Case: Ever built a mini-game with private stats?
function createPlayer(name) {
let score = 0; // 'score' is private within the 'createPlayer' scope
return { // Returns an object with methods that have closure over 'score'
getScore: () => score, // Method to get the score (read-only access)
addPoints: (points) => (score += points), // Method to modify the score
};
}
const player = createPlayer("Alex"); // Create a player object with private 'score'
player.addPoints(10); // Add points using the 'addPoints' method
player.addPoints(5); // Add more points
console.log(player.getScore()); // 15 // Access the score using 'getScore'
console.log(player.score); // undefined (score’s private!) // Trying to access 'score' directly from outside results in undefined
Thanks to closures, score is locked away, safe from meddling hands. It’s like a secret vault—only the returned methods can touch it.
new and this: The Object Factory Dream Team
Now let’s switch gears and talk about new and this. These two are the backbone of creating objects in JS, but they can feel like a rollercoaster if you don’t know the rules. Let’s break it down with some code and a few “aha!” moments.
Meet this: The Shape-Shifter
this is JavaScript’s chameleon—it changes depending on how a function is called. By itself, it’s a bit of a wild card:
function whoAmI() {
console.log(this); // In non-strict mode, 'this' refers to the global object (Window in browsers)
}
whoAmI(); // Window (or undefined in strict mode)
But slap it inside an object, and it gets cozy:
const dog = {
name: "Kallu",
bark() {
console.log(`Woof, I’m ${this.name}!`); // 'this' refers to the 'dog' object because 'bark' is called as a method of 'dog'
},
};
dog.bark(); // Woof, I’m Kallu! // 'this.name' resolves to 'dog.name'
this points to dog because the method was called on it. Simple, right? But what if we want to create objects dynamically? Enter new.
new: The Blueprint Activator
The new keyword is like hitting the “start” button on an object factory. It creates a new object, sets this to point to it, and runs a constructor function to set it up. Here’s how it works:
function Car(make, model) {
this.make = make; // 'this' refers to the new object being created
this.model = model;
this.drive = function () {
console.log(`Vroom! ${this.make} ${this.model} is rolling!`); // 'this' inside 'drive' also refers to the 'Car' object
};
}
const myCar = new Car("Toyota", "Corolla"); // 'new' keyword creates a new object, sets 'this' to it, and calls 'Car' as a constructor
myCar.drive(); // Vroom! Toyota Corolla is rolling! // Calling 'drive' on 'myCar'
What’s happening behind the scenes? When you use new:
A shiny new object is born.
this gets tied to that object.
The constructor runs, slapping properties onto this.
The object gets returned (unless you override it).
Let’s prove it:
function Test() {
console.log(this); // {} // 'this' is initially an empty object when 'new' is used
this.value = 42; // Properties are added to 'this' object
}
const test = new Test(); // 'new' creates and returns the object
console.log(test.value); // 42 // Accessing the 'value' property of the created object
Fresh object, fresh this, fresh possibilities!
this Can Be Sneaky
Without new, this might not behave like you expect:
function BadCar(make) {
this.make = make; // Oops, no 'new'! 'this' will refer to the global object (window in browsers)
}
BadCar("Honda"); // Calling 'BadCar' without 'new'
console.log(window.make); // "Honda" (uh-oh!) // 'make' property is accidentally attached to the global 'window' object
Moral of the story? Use new with constructors, or this might crash somewhere unexpected.
Real-World Use Case: Building a game character:
function Hero(name) {
this.name = name; // 'this' refers to the new 'Hero' object
this.health = 100;
this.attack = function () {
console.log(`${this.name} swings for 20 damage!`); // 'this' inside 'attack' refers to the 'Hero' object
};
}
const warrior = new Hero("Conan"); // Create a new 'Hero' object using 'new'
warrior.attack(); // Conan swings for 20 damage! // Calling the 'attack' method on the 'warrior' object
Now you’ve got a reusable blueprint for heroes. Add some closures for private stats, and you’re golden:
function Hero(name) {
let secretPower = "Strength"; // 'secretPower' is private due to closure
this.name = name; // 'this' refers to the 'Hero' object
this.revealPower = () => console.log(`${name}’s power: ${secretPower}`); // 'revealPower' method has closure over 'secretPower'
}
const rogue = new Hero("Suman"); // Create a 'Hero' object
rogue.revealPower(); // Suman's power: Strength // Calling 'revealPower' method to access the private 'secretPower' via closure
Tying It All Together: Closures + new + this
Let’s mash these concepts into one epic example—a click counter for multiple buttons:
function ButtonCounter(id) {
let clicks = 0; // 'clicks' is private to each 'ButtonCounter' instance due to closure
this.element = document.querySelector(`#${id}`); // 'this' refers to the 'ButtonCounter' object; select the button element
this.countClicks = function () { // Method to count clicks; 'this' will likely be bound differently due to event listener (needs correction below)
clicks++; // Increment the private 'clicks' counter
console.log(`${id} clicked ${clicks} times!`);
};
this.element.addEventListener("click", this.countClicks.bind(this)); // Use .bind(this) to ensure 'this' inside 'countClicks' refers to the ButtonCounter object
}
const btn1 = new ButtonCounter("btn1"); // Create the first button counter
const btn2 = new ButtonCounter("btn2"); // Create the second button counter
HTML:
<button id="btn1">Click Me!</button>
<button id="btn2">No, Click Me!</button>
Click away—each button tracks its own clicks thanks to closures, and this keeps the object context clean. It’s a harmony of JS magic!
There you go—closures, new, and this unpacked with a ton of code and a sprinkle of fun. Closures give you private scope superpowers, while new and this let you churn out objects like a factory boss. Together, they’re the secret sauce to some seriously cool JavaScript.
Until next time! Keep grinding as this thing is real 💪 🙌



