Trong JavaScript, this là một từ khóa quan trọng và cũng là một khái niệm dễ gây nhầm lẫn cho nhiều lập trình viên, đặc biệt là người mới học. this đại diện cho ngữ cảnh thực thi hiện tại và giá trị của nó phụ thuộc vào cách và nơi mà nó được gọi. Dưới đây là giải thích chi tiết về từ khóa this trong các trường hợp khác nhau.

1. this Trong Phạm Vi Toàn Cục (Global Context)

Trong phạm vi toàn cục (global scope) hoặc khi được gọi từ một hàm toàn cục, this tham chiếu đến đối tượng toàn cục. Trong trình duyệt, đối tượng này chính là window.

Ví dụ:

console.log(this); // window (trong trình duyệt)

Nếu sử dụng this trong một hàm toàn cục mà không thuộc về bất kỳ đối tượng nào, nó vẫn tham chiếu đến đối tượng toàn cục:

function globalFunction() {
    console.log(this); // window (trong trình duyệt)
}
globalFunction();

2. this Trong Một Đối Tượng (Object Context)

Khi sử dụng this trong một đối tượng, this tham chiếu đến đối tượng đó, cho phép bạn truy cập các thuộc tính và phương thức của nó.

Ví dụ:

const person = {
    name: 'John',
    greet: function() {
        console.log(this.name); // 'John'
    }
};
person.greet();

Trong ví dụ này, this trong phương thức greet tham chiếu đến đối tượng person.

3. this Trong Hàm Tạo (Constructor Function)

Khi sử dụng this trong một hàm tạo (constructor function), nó tham chiếu đến đối tượng mới được tạo ra từ hàm đó.

Ví dụ:

function Person(name) {
    this.name = name;
}
const john = new Person('John');
console.log(john.name); // 'John'

Ở đây, this trong hàm tạo Person tham chiếu đến đối tượng mới (tức là đối tượng john) khi hàm được gọi bằng từ khóa new.

4. this Trong Phương Thức Mũi Tên (Arrow Function)

Với arrow function, this không bị ràng buộc theo cách thông thường. Nó kế thừa giá trị this từ ngữ cảnh mà nó được định nghĩa, thay vì từ ngữ cảnh mà nó được gọi.

Ví dụ:

const person = {
    name: 'John',
    greet: () => {
        console.log(this.name); // undefined
    }
};
person.greet();

Trong trường hợp này, this trong arrow function không tham chiếu đến đối tượng person, mà tham chiếu đến this trong ngữ cảnh bên ngoài (global context).

5. this Trong Các Sự Kiện DOM (Event Handlers)

Khi sử dụng this trong các sự kiện DOM, nó thường tham chiếu đến phần tử DOM mà sự kiện được gắn.

Ví dụ:

document.getElementById('button').addEventListener('click', function() {
    console.log(this); // button
});

Ở đây, this tham chiếu đến phần tử DOM mà sự kiện click được gán.

6. this Trong Strict Mode (Chế Độ “Strict”)

Trong Strict Mode (chế độ nghiêm ngặt), this trong một hàm toàn cục sẽ là undefined, thay vì tham chiếu đến đối tượng toàn cục như bình thường.

Ví dụ:

'use strict';
function showThis() {
    console.log(this); // undefined
}
showThis();

7. Thay Đổi Giá Trị Của this Với call(), apply(), Và bind()

JavaScript cho phép bạn thay đổi giá trị của this trong một hàm thông qua các phương thức call(), apply(), và bind().

call()apply()

Hai phương thức này đều cho phép bạn gọi một hàm với giá trị this cụ thể và các tham số được truyền vào. Sự khác biệt giữa call()apply() nằm ở cách truyền tham số.

  • call(): Truyền tham số theo cách thông thường.
  • apply(): Truyền tham số dưới dạng một mảng.

Ví dụ:

function greet() {
    console.log(this.name);
}

const person = {
    name: 'John'
};

greet.call(person); // 'John'
greet.apply(person); // 'John'

bind()

bind() tạo ra một hàm mới mà giá trị của this được ràng buộc với đối tượng cụ thể. Không giống như call()apply(), nó không gọi hàm ngay lập tức mà chỉ trả về một bản sao của hàm với giá trị this mới.

Ví dụ:

const greetPerson = greet.bind(person);
greetPerson(); // 'John'

Kết Luận

Từ khóa this trong JavaScript có thể thay đổi tùy thuộc vào ngữ cảnh gọi hàm và cách sử dụng. Việc hiểu rõ về this sẽ giúp bạn tránh được các lỗi phổ biến khi làm việc với các đối tượng và hàm trong JavaScript.