The this Keyword — Why It Confuses Everyone
this in JavaScript does not refer to the function itself or its scope — it refers to the object that called the function. But which object? That depends on HOW the function is called. There are exactly four rules.
Rule 1: Default Binding
// In non-strict mode: this = window (browser) or global (Node.js)
// In strict mode: this = undefined
function showThis() {
console.log(this); // window or undefined
}
showThis(); // standalone call → default binding
'use strict';
function strictFn() {
console.log(this); // undefined in strict mode
}
strictFn();
Rule 2: Implicit Binding
// this = the object to the left of the dot at call time
const user = {
name: 'Rahul',
greet() {
console.log('Hello, ' + this.name); // this = user
}
};
user.greet(); // Hello, Rahul ← implicit binding
// Lost binding — common bug!
const fn = user.greet;
fn(); // Hello, undefined ← this lost! (standalone call now)
Rule 3: Explicit Binding — call, apply, bind
function introduce(greeting, punct) {
console.log(`${greeting}, I'm ${this.name}${punct}`);
}
const person = { name: 'Rahul' };
// call — invoke immediately, pass args individually
introduce.call(person, 'Hello', '!'); // Hello, I'm Rahul!
// apply — invoke immediately, pass args as array
introduce.apply(person, ['Hi', '?']); // Hi, I'm Rahul?
// bind — returns a NEW function with this locked
const boundFn = introduce.bind(person, 'Hey');
boundFn('.'); // Hey, I'm Rahul.
boundFn('!'); // Hey, I'm Rahul! (greeting locked to 'Hey')
Rule 4: new Binding
function User(name, email) {
// When called with new:
// 1. A new object is created
// 2. this is set to that new object
// 3. Object is returned automatically
this.name = name;
this.email = email;
this.greet = function() {
console.log('Hi, ' + this.name); // this = new instance
};
}
const user1 = new User('Rahul', 'r@e.com');
const user2 = new User('Priya', 'p@e.com');
user1.greet(); // Hi, Rahul
user2.greet(); // Hi, Priya
Arrow Functions — Lexical this
// Arrow functions DON'T have their own this
// They inherit this from the SURROUNDING scope at definition time
const timer = {
name: 'EzyCoders',
start() {
// Regular function — this gets lost in setTimeout
setTimeout(function() {
console.log(this.name); // undefined!
}, 100);
// Arrow function — inherits this from start()
setTimeout(() => {
console.log(this.name); // EzyCoders ✅
}, 100);
}
};
timer.start();
Q: What is the order of precedence for this binding rules?
new > explicit (call/apply/bind) > implicit (object method) > default. Arrow functions ignore all four rules and always use lexical this from their enclosing scope.
Q: Can you change the this of an arrow function with bind?
No. Arrow functions have no own this — bind(), call(), and apply() do not affect them. The this inside an arrow function is determined at the time of function definition, not at call time.
Comments (0)
No comments yet. Be the first!
Leave a Comment