Trong JavaScript, giá trị của this không cố định mà được xác định động dựa trên cách hàm được gọi — không phụ thuộc vào nơi nó được khai báo. Dưới đây là các tình huống phổ biến:
1. Trong phạm vi toàn cục
- Không sử dụng strict mode:
thistrỏ đến đối tượng toàn cục.
console.log(this); // Trình duyệt: window, Node.js: global
- Chế độ strict:
thislàundefined.
"use strict";
console.log(this); // undefined
2. Gọi hàm thông thường
function display() {
console.log(this); // window hoặc global (nếu không strict)
}
display();
"use strict";
function display() {
console.log(this); // undefined
}
display();
3. Gọi qua phương thức đối tượng
Khi hàm được gọi như một phương thức, this trỏ đến đối tượng sở hữu nó.
const profile = {
title: "Developer",
introduce() {
console.log(this.title); // "Developer"
}
};
profile.introduce(); // this = profile
4. Hàm khởi tạo với từ khóa new
this sẽ trỏ đến thể hiện mới được tạo ra.
function Job(role) {
this.role = role;
}
const engineer = new Job("Frontend");
5. Gán this thủ công bằng call, apply, bind
function printRole() {
console.log(this.role);
}
const dev = { role: "Backend" };
const qa = { role: "Tester" };
printRole.call(dev); // "Backend"
printRole.apply(qa); // "Tester"
const fixedPrint = printRole.bind(dev);
fixedPrint(); // "Backend" (không đổi)
6. Arrow function
Không có this riêng, kế thừa từ ngữ cảnh cha tại thời điểm định nghĩa.
const profile = {
title: "Manager",
report: () => {
console.log(this.title); // this lấy từ scope ngoài → thường là global
}
};
profile.report(); // undefined (vì global không có title)
Ứng dụng thực tế để giữ đúng ngữ cảnh:
const counter = {
value: 0,
begin() {
setInterval(() => {
console.log(++this.value); // this vẫn là counter
}, 1000);
}
};
counter.begin();
7. Trong xử lý sự kiện DOM
this tự động trỏ đến phần tử kích hoạt sự kiện.
btn.addEventListener("click", function() {
console.log(this); // phần tử button
});
8. Vấn đề thường gặp trong callback
Hàm callback truyền vào có thể làm mất this gốc:
const profile = {
title: "Designer",
announce() {
setTimeout(function() {
console.log(this.title); // this sai → global/undefined
}, 500);
}
};
profile.announce();
Cách khắc phục:
- Dùng arrow function:
setTimeout(() => console.log(this.title), 500) - Lưu tạm
this:const ctx = this; - Sử dụng
bind:setTimeout(this.announce.bind(this), 500)
Bảng tổng hợp nhanh
| Tình huống | Giá trị this |
|---|---|
| Toàn cục | global object / undefined (strict) |
| Phương thức đối tượng | Đối tượng gọi phương thức |
| Hàm tạo với new | Thể hiện mới |
| call/apply/bind | Đối tượng được chỉ định |
| Arrow function | Kế thừa từ scope cha lúc định nghĩa |
| Sự kiện DOM | Phần tử kích hoạt |
| Callback chưa xử lý | global / undefined |
Mấu chốt để hiểu this là xem xét cách hàm được gọi. Arrow function và các phương thức bind giúp kiểm soát ngữ cảnh hiệu quả.