The `this` Keyword

Understand who owns the function, how `call`, `apply`, and `bind` work, and why arrow functions treat `this` differently.

1. What is `this`?

In JavaScript, this simply refers to "the object currently executing this function".

💡 Think of the Pronoun "I" in Conversation

Who does "I" refer to? It depends entirely on who is talking right now! If Alex says "I love pizza", it means Alex. If Priya says "I love pizza", it means Priya. In JavaScript, this depends on which object called the function!

const user1 = {
    name: "Alex",
    greet() {
        console.log("Hello, I am " + this.name);
    }
};

const user2 = {
    name: "Priya",
    greet() {
        console.log("Hello, I am " + this.name);
    }
};

user1.greet(); // "Hello, I am Alex" (user1 called greet)
user2.greet(); // "Hello, I am Priya" (user2 called greet)
Output
Hello, I am Alex
Hello, I am Priya

2. The 4 Simple Rules (How `this` is Decided)

To know what this points to, look at how the function is called:

1. Object Method (Implicit)

Called with a dot: person.speak(). this is the object before the dot (person).

2. Explicit (call, apply, bind)

You explicitly command JavaScript who this should be using .call(obj) or .bind(obj).

3. Constructor (new)

Called with new User(). this is the brand new object just created.

4. Standalone Call (Default)

Called alone: show(). this is global window (or undefined in strict mode).

3. Taking Control: `call()`, `apply()`, and `bind()`

These 3 built-in methods let you borrow functions and set this manually:

function introduce(city, role) {
    return `I am ${this.name} from ${city}, working as a ${role}.`;
}

const developer = { name: "Anshuman" };

// 1. call(): Calls function immediately, arguments passed one by one:
console.log(introduce.call(developer, "Bengaluru", "Frontend Lead"));

// 2. apply(): Calls function immediately, arguments passed as an array []:
console.log(introduce.apply(developer, ["Bengaluru", "Frontend Lead"]));

// 3. bind(): Does NOT call immediately. Returns a new permanently bound function:
const boundIntro = introduce.bind(developer, "Bengaluru");
console.log(boundIntro("Fullstack Developer"));
Output
I am Anshuman from Bengaluru, working as a Frontend Lead.
I am Anshuman from Bengaluru, working as a Frontend Lead.
I am Anshuman from Bengaluru, working as a Fullstack Developer.

4. Arrow Functions Don't Have Their Own `this`!

Arrow functions do not get their own this. Instead, they borrow (inherit) this from whatever scope is around them:

Regular Function Loses `this` ❌

Inside callbacks or setTimeout, regular functions forget who called them and revert to undefined.

Arrow Function Keeps `this` ✅

Arrow functions lock onto the surrounding object's this, making them perfect for event callbacks and timers!

const team = {
    title: "Engineering",
    members: ["Alex", "Priya"],
    printMembers() {
        // Arrow function keeps 'this.title':
        this.members.forEach(member => {
            console.log(`${member} is on the ${this.title} team`);
        });
    }
};

team.printMembers();
Output
Alex is on the Engineering team
Priya is on the Engineering team

5. Quick Comparison Table

Tool When to Use How arguments are passed Executes immediately?
func.call(obj, a, b) Borrow a function with a specific this Comma-separated list (a, b) Yes
func.apply(obj, [a, b]) Borrow a function with arguments already in a list Array list ([a, b]) Yes
func.bind(obj, a) Save a copy to run later (e.g. event handlers) Comma-separated list No (Returns copy)
() => {} (Arrow) Callbacks inside methods that need parent's this Normal parameters When called

6. `this` Keyword Interview Deck

Test your knowledge on implicit vs explicit binding, method extraction lost context, arrow function lexical binding, and hard-binding with bind:

🎯 `this` Keyword Interview Deck
Question 1 of 5
⭐ Easy • Implicit Binding Implicit this
const user = {
    name: "Alex",
    getName() {
        return this.name;
    }
};

console.log(user.getName());
What will be logged to the console?
A) "Alex"
B) undefined
C) TypeError: this.name is undefined
D) null
⚡ Medium • Lost Context Trap Default Binding
const user = {
    name: "Alex",
    getName() {
        return this.name;
    }
};

const get = user.getName;
console.log(get());
What will be logged when get() is called?
A) "Alex"
B) undefined
C) ReferenceError: name is not defined
D) "user"
⚡ Medium • Arrow Functions in Objects Arrow Function this
const dev = {
    name: "Sam",
    greet: () => {
        return `Hi, ${this.name}`;
    }
};

console.log(dev.greet());
What will be logged to the console?
A) "Hi, Sam"
B) "Hi, undefined"
C) TypeError
D) ReferenceError
⭐ Easy • Explicit Binding with call Explicit Binding
function greet(greeting, punctuation) {
    return `${greeting}, ${this.name}${punctuation}`;
}

const person = { name: "Sara" };
console.log(greet.call(person, "Hello", "!"));
What will be logged to the console?
A) "Hello, Sara!"
B) "Hello, undefined!"
C) TypeError: call is not a function
D) undefined
🔥 Hard • Permanent Hard-Binding bind Immutability
function show() {
    return this.id;
}

const obj1 = { id: 1 };
const obj2 = { id: 2 };

const bound = show.bind(obj1);
console.log(bound.call(obj2));
What will be logged to the console?
A) 1
B) 2
C) undefined
D) TypeError

7. Practice Challenge

🎯 Coding Challenge: Function Borrowing & Binding

1. Create an independent function announce(location) that returns `${this.speaker} is presenting '${this.title}' at ${location}`.
2. Execute announce on the presenter object using .call().
3. Create a permanently bound version using .bind() and execute it with "Online Webinar".

Your output will appear here.