π₯ THE ULTIMATE JS LESSON β this Keyword (Browser & Node)
Greetings, fellow developers! Today, we dive into a comprehensive exploration of the this keyword and the powerful call / apply / bind methods.
π Repo: javascript-complete-mastery
π 1. What is this in JavaScript?
this depends entirely on HOW a function is called, not where it is written.
π§ 2. 5 Core Rules of this (Browser + Node)
Rule 1 β Global Context
Browser
console.log(this);
π window
Node
console.log(this);
π {}
Rule 2 β Function Context
Non-strict mode
function test() {
console.log(this);
}
test();
π Browser β window
π Node β global
Strict mode
"use strict";
function test() {
console.log(this);
}
test();
π undefined
Rule 3 β Method Call (Object Method)
this = object before dot
const user = {
name: "Usman",
greet() {
console.log(this.name);
}
};
user.greet();
β "Usman"
Rule 4 β Constructor / Class
function Person(name) {
this.name = name;
}
const p = new Person("Usman");
console.log(p.name);
π this refers to the new object
Rule 5 β Arrow Functions (NO own this)
const obj = {
value: 10,
test: () => {
console.log(this);
}
};
obj.test();
π Browser: window
π Node: {}
π₯ Browser vs Node Quick Comparison
| Scenario | Browser | Node |
|---|---|---|
| Global context | window |
{} |
| Function (non strict) | window |
global |
| Function (strict) | undefined |
undefined |
| Method | Object | Object |
| Arrow | Parent scope | Parent scope |
β‘ 3. Deep Examples (Tricky)
Example β Losing this
const user = {
name: "Usman",
greet() {
console.log(this.name);
}
};
const x = user.greet;
x();
β undefined
Example β Fix with bind
const x = user.greet.bind(user);
x();
β "Usman"
Arrow inside methods
const user = {
name: "Usman",
greet: function () {
setTimeout(() => {
console.log(this.name);
}, 100);
}
};
user.greet();
β "Usman"
Arrow in object (incorrect assumption)
const obj = {
a: 10,
print: () => console.log(this.a)
};
obj.print();
β undefined
π§© Event Listeners
Normal function
button.addEventListener("click", function() {
console.log(this);
});
π this = button element
Arrow function
button.addEventListener("click", () => {
console.log(this);
});
π this = window
π¦ Node.js Module Wrapper
(function(exports, require, module, __filename, __dirname) {
// code
})();
So:
console.log(this); // {}
π Summary Cheat Sheet
this = depends on how the function is called
Browser
- Global β window
- Function non strict β window
- Strict β undefined
- Method β object
- Arrow β parent
Node
- Global β {}
- Function non strict β global
- Strict β undefined
- Method β object
- Arrow β parent
ποΈββοΈ PRACTICE SECTION
β EASY (3)
Problem 1
console.log(this);
β Browser β window
β Node β {}
Problem 2
function test() {
console.log(this);
}
test();
β Browser β window
β Node β global
Problem 3
const obj = {
a: 5,
show() {
console.log(this.a);
}
};
obj.show();
β 5
β‘ MEDIUM (3)
Problem 1
const obj = {
a: 10,
b: () => console.log(this.a)
};
obj.b();
β undefined
Problem 2
"use strict";
function x() {
console.log(this);
}
x();
β undefined
Problem 3
const user = {
name: "Ali",
greet() {
setTimeout(function() {
console.log(this.name);
}, 0);
}
};
user.greet();
β undefined
π₯ HARD (4)
Problem 1
const obj = {
name: "Usman",
greet() {
return () => console.log(this.name);
}
};
const x = obj.greet();
x();
β "Usman"
Problem 2
class A {
constructor() {
this.num = 100;
}
show() {
console.log(this.num);
}
}
const a = new A();
const s = a.show;
s();
β undefined
Problem 3
const obj = {
x: 15,
y: {
z: function() {
console.log(this.x);
}
}
};
obj.y.z();
β undefined
Problem 4
let a = {
value: 50,
print: function() {
(function() {
console.log(this.value);
})();
}
};
a.print();
β undefined
π THE ULTIMATE JS LESSON β call(), apply(), bind()
JavaScript gives us three powerful methods to manually control the value of this inside a function.
These are essential for interview questions, real-world bug fixing, and writing professional code.
π₯ 1. Why do we need call/apply/bind?
Because sometimes, a function loses its this:
function greet() {
console.log(this.name);
}
const user = { name: "Usman" };
greet(); // β undefined
We want to run greet with this = user.
Thatβs where these methods come in.
π§ 2. call() β calls the function immediately
func.call(thisValue, arg1, arg2, ...)
Example
function greet(age) {
console.log(this.name, age);
}
const user = { name: "Usman" };
greet.call(user, 22);
β Sets this = user
β Executes immediately
β Arguments passed one-by-one
π§ 3. apply() β same as call, but arguments in an array
func.apply(thisValue, [arg1, arg2, ...])
Example
greet.apply(user, [22]);
β Same output
β Just a different argument format
π§ 4. bind() β returns a NEW function with fixed this
const newFn = func.bind(thisValue, arg1, arg2);
Example
const greetUser = greet.bind(user, 22);
greetUser();
β Does NOT run immediately
β Creates a new function with permanent this
π 5. The Three in One Line
call β call immediately (args individually)
apply β call immediately (args in array)
bind β return new function (does NOT run)
π¦ 6. Real-world Uses
β Borrowing methods
let obj1 = { name: "Ali" };
let obj2 = { name: "Usman" };
function sayHi() {
console.log("Hi " + this.name);
}
sayHi.call(obj2);
β Using Array methods on non-arrays
const nums = {
0: 4,
1: 8,
length: 2
};
console.log(Array.prototype.join.call(nums, "-"));
β Fixing this in event handlers
button.addEventListener("click", obj.method.bind(obj));
β Currying with bind
function multiply(a, b) {
return a * b;
}
const double = multiply.bind(null, 2);
console.log(double(5)); // 10
𧨠7. Tricky & Important Behaviors
β Arrow functions IGNORE call/apply/bind
const obj = { a: 10 };
const x = () => console.log(this.a);
x.call(obj); // β still not obj
Arrow functions use lexical this, so you cannot change it.
β bind creates a new function (original stays unchanged)
function a() {}
const b = a.bind({});
console.log(a === b); // false
β Multiple binds β first one wins
const x = greet.bind(obj1).bind(obj2);
x(); // uses obj1
β‘ 8. Browser vs Node?
No difference in behavior.
call/apply/bind work the same in both.
Only the default this differs, not these methods.
π§© 9. Practice Problems
β EASY (3 Problems)
Problem 1 β Output?
function say() {
console.log(this.x);
}
const obj = { x: 10 };
say.call(obj);
Solution
10
Problem 2 β Output?
function sum(a, b) {
console.log(a + b);
}
sum.apply(null, [5, 7]);
Solution
12
Problem 3 β Output?
function greet(name) {
console.log("Hi " + name);
}
const g = greet.bind(null, "Usman");
g();
Solution
Hi Usman
β‘ MEDIUM (3 Problems)
Problem 1 β Output?
const user = {
name: "Ali",
say() {
console.log(this.name);
}
};
const fn = user.say;
fn.call(user);
Solution
Ali
Problem 2 β Output?
function add(a, b) {
console.log(this.x + a + b);
}
const obj = { x: 5 };
add.call(obj, 10, 15);
Solution
30
Problem 3 β Output?
function intro(age, country) {
console.log(this.name, age, country);
}
const p = { name: "Usman" };
intro.apply(p, [22, "PK"]);
Solution
Usman 22 PK
π₯ HARD (4 Problems)
Problem 1 β Output?
const a = { value: 50 };
function print() {
console.log(this.value);
}
const b = print.bind(a);
b.call({ value: 100 });
Solution
50
Problem 2 β Output?
const obj = {
x: 10,
y: function() {
console.log(this.x);
}
};
const z = obj.y.bind({ x: 99 });
z();
Solution
99
Problem 3 β Output?
function show() {
console.log(this.a);
}
const o1 = { a: 1 };
const o2 = { a: 2 };
const f = show.bind(o1);
f.call(o2);
Solution
1
Problem 4 β Output?
function multiply(a, b, c) {
console.log(a * b * c);
}
const f = multiply.bind(null, 2);
f.apply(null, [3, 4]);
Solution
24
Congratulations on mastering this, call(), apply(), and bind()! To further enhance your JavaScript journey, Iβve developed a free, structured repository featuring topic-by-topic training, ranging from beginner to advanced levels, organized into a 42-day mastery plan. Completing this resource will significantly ease your transition into frameworks and stacks like React, Node, and Next.js.
πjavascript-complete-mastery
Top comments (0)