Full Stack / 6 min read
Mastering JavaScript’s this: Why It Works in Classes but Confuses Developers in Factory Functions
A beginner-friendly guide to understanding how this behaves in JavaScript — with classes, factory functions, and a simple 5-minute rule
Mastering JavaScript’s this: Why It Works in Classes but Confuses Developers in Factory Functions
A beginner-friendly guide to understanding how this behaves in JavaScript — with classes, factory functions, and a simple 5-minute rule

If there is one JavaScript concept that consistently confuses developers, it is the this keyword. Many programmers assume that this refers to the object where the function is written. However, JavaScript behaves differently.
In JavaScript, this depends on how a function is called, not where it is defined. This small detail explains why code using this works perfectly in classes, but can behave unexpectedly in factory functions.
In this article, we will explore:
- What
thisactually means in JavaScript - Why does it work naturally in classes
- Why can it fail in factory functions
- 5-minute rule to learn this: a practical mental model to determine the value of quickly
this
Let’s start with the fundamentals.
What Does this Mean in JavaScript?
In simple terms, this usually refers to the object that calls the function.
A quick way to visualise this is:
When a method is called usingobject.method(),thisrefers to the object before the dot.
Example:
const user = {
name: "Neha",
greet() {
console.log(this.name);
}
};
user.greet();Output:
NehaHere the function is called as:
user.greet()So inside greet(), this refers to the user object.
Why this Works Smoothly in Classes
Classes are structured so that methods operate on the instance that created them. When a class instance calls a method, this automatically points to that instance.
Example:
class Counter {
constructor() {
this.count = 0;
}
increment() {
this.count++;
console.log(this.count);
}
}
const counter = new Counter();
counter.increment();What Happens Internally
When we create an instance:
const counter = new Counter();JavaScript constructs an object like this:
counter
├─ count
└─ increment()When the method runs:
counter.increment()The object before the dot is counter, so inside the method:
this === counterTherefore:
this.countcorrectly accesses the property stored in the object.
This is why working with this in classes usually feels predictable.
How Factory Functions Work
A factory function simply returns an object.
Example:
function createCounter() {
let count = 0;
return {
increment() {
count++;
console.log(count);
}
};
}
const counter = createCounter();
counter.increment();Here the method accesses count directly from the outer function scope.
This works because JavaScript functions remember variables from their surrounding environment. This feature is known as a closure.
Conceptually:
createCounter()
│
└── count
│
└── returned object
└── increment()The increment() function continues to access count even after createCounter() has finished executing.
Why this Can Break in Factory Functions
Now, let’s attempt the same logic using this.
function createCounter() {
this.count = 0;
return {
increment() {
this.count++;
console.log(this.count);
}
};
}
const counter = createCounter();
counter.increment();At first glance, this looks reasonable, but the behavior changes because of how JavaScript assigns this.
Step 1: The Function Executes
Inside the function:
this.count = 0But the function is called like this:
createCounter()There is no object before the function call, so this does not refer to the returned object.
Step 2: A New Object Is Returned
The function returns a different object:
counter
└─ increment()Notice that this object does not contain count.
Step 3: The Method Runs
When we call:
counter.increment()JavaScript applies its rule again:
this = object before the dotSo inside the method:
this === counterBut the object only contains:
counter
└─ increment()Since count is not present, the method cannot access the expected data.
The Recommended Pattern for Factory Functions
To avoid confusion, factory functions typically do not rely on this. Instead, they use variables inside the function scope.
Example:
function createCounter() {
let count = 0;
return {
increment() {
count++;
console.log(count);
}
};
}This pattern is reliable because all methods share access to the same closure variables.
The 5-Minute Rule to Predict this
When reading unfamiliar JavaScript code, developers often wonder what this refers to. A simple mental checklist can help you determine it quickly.
1. Was the function called with new?
If a function is called using new, this refers to the newly created object.
Example:
const obj = new Counter();Here:
this → obj2. Is it called using object.method()?
If a function is called through an object, this refers to that object.
Example:
user.greet()Here:
this → user3. Was .call(), .apply(), or .bind() used?
These methods explicitly define what this should be.
Example:
greet.call(user);Here:
this → user4. Is it an arrow function?
Arrow functions do not create their own this. Instead, they inherit this from the surrounding scope.
Example:
const arrow = () => {
console.log(this);
};Here this comes from the outer environment.
5. Otherwise: Default Behaviour
If none of the above conditions apply, the behaviour depends on the execution mode:
- In strict mode →
thisisundefined - In non-strict mode →
thisrefers to the global object
Key Takeaways
thisin JavaScript depends on how a function is called, not where it is defined.- In class methods,
thisrefers to the instance of the class. - Factory functions usually return a new object, which can cause
thisto behave differently. - Closures are often a safer pattern for sharing data inside factory functions.
- A simple 5-step rule can help you quickly determine what
thisrefers to in any code.
Understanding how this Behaves removes much of the confusion many developers experience in JavaScript. Once you begin analysing how a function is invoked, predicting the value of this becomes much easier, and debugging becomes significantly faster.
At Dev Simplified, We Value Your Feedback 📊
👉 To read more such articles on Javascript, visit here
👉 Follow us not to miss any updates.
👉 Have any suggestions? Let us know in the comments!