Vì this trong JavaScript được quyết định lúc gọi hàm, không phải lúc định nghĩa.
- Khi gán method ra biến, bạn chỉ lấy tham chiếu tới hàm, phần "chủ thể gọi" (
obj.) không đi kèm. - Gọi trần
fn()thìthislàundefinedở strict mode / module (hoặcglobalThisở sloppy mode).
js
const counter = {
count: 0,
inc() { this.count++; },
};
counter.inc(); // OK — this = counter
const inc = counter.inc;
inc(); // TypeError: Cannot read properties of undefined
setTimeout(counter.inc, 100); // cùng lỗi — callback được gọi trầnBa cách sửa:
js
const bound = counter.inc.bind(counter); // 1. bind — tạo hàm mới cố định this
setTimeout(() => counter.inc(), 100); // 2. arrow wrapper — giữ nguyên lời gọi obj.method()
class Counter {
count = 0;
inc = () => { this.count++; }; // 3. class field arrow — this lấy từ scope tạo instance
}Đây là nguyên nhân kinh điển của lỗi Cannot read properties of undefined khi truyền method làm callback cho addEventListener, map, hay props React.
Cách 2 thường được ưu tiên vì rõ ràng và không tạo hàm bind rải rác.