Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> JavaScript

Từ khóa this trong JavaScript - Giải thích chi tiết

this trong JavaScript là từ khóa tham chiếu đến **object mà hàm đang được thực thi thuộc về**. Giá trị của this được xác định tại **thời điểm gọi hàm (runtime)**, không phải tại nơi định nghĩa.

Quy tắc xác định this (theo thứ tự ưu tiên):

Loại gọiCú phápGiá trị thisVí dụ
New bindingnew Fn()Instance mới tạonew Person()
Explicit bindingfn.call(obj), fn.apply(obj), fn.bind(obj)Object truyền vàofn.call(user)
Implicit bindingobj.method()Object chứa methoduser.greet()
Default bindingfn() (standalone)Global object (window) hoặc undefined (strict mode)greet()
Arrow function() => {}Lexical this (kế thừa từ scope bên ngoài)const fn = () => this

Ví dụ minh họa

<!DOCTYPE html>
<html lang="vi">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>JavaScript this Keyword</title>
  <style>
    body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; }
    .sample { font-size: 18px; font-weight: 500; margin: 10px 0; color: red; }
    .result { font-size: 18px; font-weight: 500; margin: 10px 0; color: green; }
    button { padding: 8px 16px; cursor: pointer; }
  </style>
</head>
<body>
  <h1>JavaScript this Keyword</h1>
  <div class="sample" id="sample"></div>
  <div class="result" id="result"></div>
  <button class="Btn" id="btn">NHẤN VÀO ĐÂY</button>
  <h3> Nhấn nút để xem 'this' tham chiếu đến object nào trong các ngữ cảnh </h3>
  <script>
    const sampleEle = document.querySelector("#sample");
    const resEle = document.querySelector("#result");
    
    // 1. Default binding (global/undefined)
    const globalThis = this; // window (non-strict) hoặc undefined (strict)
    
    // 2. Function declaration - default binding
    function regularFunction() {
      return this;
    }
    
    // 3. Method trong object - implicit binding
    const testObj = {
      a: 22,
      check() {
        return this; // this = testObj
      }
    };
    
    // 4. Arrow function - lexical this
    const arrowFn = () => this; // this = globalThis (window)
    
    // 5. Event handler - this = element nhận event
    document.querySelector("#btn").addEventListener("click", function() {
      sampleEle.innerHTML = "";
      
      // Default binding
      sampleEle.innerHTML += "Hàm thường (default binding): " + regularFunction() + "
"; // Implicit binding sampleEle.innerHTML += "Method trong object (implicit): " + testObj.check() + "
"; // Global this sampleEle.innerHTML += "This toàn cục: " + globalThis + "
"; // Arrow function sampleEle.innerHTML += "Arrow function (lexical): " + arrowFn() + "
"; // Event handler - this = button element sampleEle.innerHTML += "Event handler (this = button): " + this.tagName + "#" + this.id + "
"; // call/apply/bind demo function greet(greeting, punctuation) { return `${greeting}, ${this.name}${punctuation}`; } const user = { name: "Rohan" }; resEle.innerHTML = "call(): " + greet.call(user, "Xin chào", "!") + "
"; resEle.innerHTML += "apply(): " + greet.apply(user, ["Chào", "."]) + "
"; const boundGreet = greet.bind(user, "Hello"); resEle.innerHTML += "bind(): " + boundGreet("?") + "
"; }); </script> </body> </html>

Kết quả

Khi nhấn nút, hiển thị this trong các ngữ cảnh khác nhau:

  • Hàm thường (standalone): window (hoặc undefined strict mode)
  • Method trong object: object chứa method (testObj)
  • Arrow function: kế thừa this từ scope bên ngoài (global)
  • Event handler: element nhận event (button)
  • call/apply/bind: object được truyền vào

Các lỗi thường gặp & cách khắc phục:

// ❌ Mất this trong callback
const obj = {
  name: "JS",
  logName() {
    setTimeout(function() {
      console.log(this.name); // undefined (this = window)
    }, 100);
  }
};

// ✅ Sửa: Arrow function (lexical this)
setTimeout(() => console.log(this.name), 100);

// ✅ Sửa: bind
setTimeout(function() { console.log(this.name); }.bind(this), 100);

// ✅ Sửa: lưu this vào biến
const self = this;
setTimeout(function() { console.log(self.name); }, 100);

Tóm tắt: this phụ thuộc vào cách hàm được gọi, không phải nơi định nghĩa. Arrow function không có this riêng - kế thừa từ scope bao quanh.