Cơ chế xác định giá trị this trong JavaScript

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: this trỏ đến đối tượng toàn cục.
console.log(this); // Trình duyệt: window, Node.js: global
  • Chế độ strict: thisundefined.
"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ốngGiá trị this
Toàn cụcglobal 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 newThể hiện mới
call/apply/bindĐối tượng được chỉ định
Arrow functionKế thừa từ scope cha lúc định nghĩa
Sự kiện DOMPhầ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ả.

Thẻ: JavaScript this arrow-function call-apply-bind dom-event

Đăng vào ngày 11 tháng 6 lúc 03:51