In the world of JavaScript, there is a tiny keyword that causes a lot of confusion for developers, from beginners to experienced coders. It’s called this. The this keyword doesn’t work like in other programming languages, and its “magic” lies in the fact that its value changes depending on the context in which it is called.

Have you ever written some code and used console.log(this) only to get an unexpected result? 🤔 Don’t worry, you’re not alone. This article will help you fully decode this, turning it from a vague concept into a powerful tool in your hands.
What is the this keyword in JavaScript?
Simply put, this is a reference to an object. But which object? The answer is: It’s the object that is the execution context of the current function.
Here’s the key: the value of this is not determined when the function is written, but when the function is called. How you call a function determines what this is.
Understanding this helps you:
- Write effective object-oriented code.
- Work with DOM events accurately.
- Use advanced methods like
call,apply, andbind. - Avoid hard-to-debug hidden bugs.
Let’s explore the 4 golden rules that determine the value of this.
🎯 Top 4 "Golden Rules" for Determining this
1. Default Rule: Global Context
When a function is called independently (not as a method of an object), this refers to the global object.
- In browsers, that’s the
windowobject. - In Node.js, it’s the
globalobject.
function showMeThis() {
console.log(this)
}
showMeThis() // In browsers, this will be the Window object
Note on "Strict Mode": If you use 'use strict';, this in this case will be undefined to prevent accidental modification of the global object.
2. Implicit Rule: Object Context
This is the most common case. When a function is called as a method of an object, this refers to the object that called the method.
Look at the object before the dot .. That’s your this!
const person = {
name: 'John Doe',
greet: function () {
console.log(`Hello, my name is ${this.name}.`)
},
}
person.greet() // "Hello, my name is John Doe."
// Here, `this` is the `person` object because `person` called the `greet` function.
3. Explicit Rule: call, apply, and bind
JavaScript gives us a way to explicitly tell a function what this should be, no matter how it’s called. That’s where call, apply, and bind shine. ✨
call(thisArg, arg1, arg2, ...): Executes the function immediately, withthisset tothisArgand arguments passed individually.apply(thisArg, [arg1, arg2, ...]): Likecall, but arguments are passed as an array.bind(thisArg): Does not execute the function immediately. Instead, it returns a new function withthispermanently set tothisArg.
function introduce(city, country) {
console.log(`I am ${this.name} from ${city}, ${country}.`)
}
const user1 = { name: 'Alice' }
const user2 = { name: 'Bob' }
// Using call
introduce.call(user1, 'New York', 'USA') // I am Alice from New York, USA.
// Using apply
introduce.apply(user2, ['Tokyo', 'Japan']) // I am Bob from Tokyo, Japan.
// Using bind
const introduceAlice = introduce.bind(user1, 'London', 'UK')
introduceAlice() // I am Alice from London, UK.
bind is especially useful when working with callbacks or event handlers, where the context of this is easily “lost”.
4. new Rule: Constructor Context
When a function is called with the new keyword (to create an instance of an object), the following happens:
- A brand new empty object is created.
- This empty object is assigned to
this. - The function is executed.
- The new object is returned (unless the function explicitly returns another object).
function Car(make, model) {
this.make = make
this.model = model
this.info = function () {
return `${this.make} ${this.model}`
}
}
const myCar = new Car('Toyota', 'Camry')
console.log(myCar.info()) // "Toyota Camry"
// Here, `this` inside `Car` refers to the newly created `myCar` object.
💡 Special Case: Arrow Functions
Arrow functions, introduced in ES6, handle this in a completely different way and are a “lifesaver” in many cases.
Arrow functions do not have their own this. Instead, they “borrow” this from the nearest enclosing (lexical) scope where they are defined.
Let’s look at the classic setTimeout example:
const counter = {
count: 0,
start: function () {
// The old way, often buggy
setTimeout(function () {
// Here, `this` is `window`, not `counter`!
console.log(`Wrong: ${this.count}`) // NaN or undefined
}, 1000)
// The arrow function solution
setTimeout(() => {
// Here, `this` is inherited from the `start` function.
// And `this` in `start` is `counter`.
this.count++
console.log(`Correct: ${this.count}`) // 1
}, 1000)
},
}
counter.start()
Because of this convenience, arrow functions are a great choice for callbacks and event handlers. However, you should not use arrow functions for object methods or constructors, as they will not get this as the object as expected.
Summary: The Precedence Order of this
So, when multiple rules could apply, which one wins?
new: If the function is called withnew,thisis the newly created object.call,apply,bind: If the function is called with these methods,thisis the explicitly specified object.- Object Context: If the function is called as a method,
thisis the object containing it. - Default: If none of the above,
thisis the global object (orundefinedin strict mode).
The this keyword can be tricky, but it follows a logical and consistent set of rules. The key to mastering it is always asking yourself: "How is this function being CALLED?"
By understanding the 4 golden rules and the difference with arrow functions, you’ll not only solve one of JavaScript’s trickiest problems but also unlock the door to writing cleaner, more effective, and maintainable code.
Good luck on your journey to mastering JavaScript!
![[JS Basics] Manipulating the DOM with JavaScript: A Detailed Guide for Beginners](/images/blog/manipulating-the-dom-using-javascript.webp)
![[JS Basics] How to Set Up a JavaScript Runtime Environment](/images/blog/setting-up-the-javascript-runtime-environment.webp)
![[JS Basics] Conditional Statements in JavaScript: Examples & Effective Usage](/images/blog/conditional-statements-in-javascript.webp)
![[JS Basics] LocalStorage, SessionStorage, and Cookies: When to Use Which?](/images/blog/local-storage-and-session-storage-and-cookies.webp)