Sử dụng và trường hợp áp dụng của call và apply trong JavaScript

Trong JavaScript, các phương thức callapply được sử dụng để ràng buộc ngữ cảnh thực thi (giá trị this) của một hàm và truyền tham số khi gọi hàm. Sự khác biệt chính giữa chúng nằm ở cách truyền tham số, điều này quyết định việc sử dụng chúng trong các trường hợp cụ thể.

Tác dụng

  1. Thay đổi hướng this Bắt buộc ràng buộc this trong hàm đến đối tượng chỉ định, cho phép hàm thực thi trong ngữ cảnh cụ thể.
const obj1 = { name: "Alice" };
const obj2 = { name: "Bob" };

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

greet.call(obj1); // In ra "Alice"
greet.apply(obj2); // In ra "Bob"
  1. Truyền tham số
  • call: Truyền tham số dưới dạng danh sách (ví dụ: func.call(thisArg, arg1, arg2, ...).
  • apply: Truyền tham số dưới dạng mảng hoặc cấu trúc giống mảng (ví dụ: func.apply(thisArg, [argsArray]).

Sự khác biệt

Phương thức Cách truyền tham số Trường hợp sử dụng
call Truyền từng tham số (cách nhau bởi dấu phẩy) Khi số lượng tham số đã biết và rõ ràng
apply Truyền tham số qua mảng Khi số lượng tham số không xác định hoặc đã có sẵn mảng

Trường hợp sử dụng

1. Lent Method từ đối tượng khác

Khi một đối tượng cần sử dụng phương thức từ đối tượng khác:

const arrayLike = { 0: "a", 1: "b", length: 2 };
// Sử dụng phương thức push của mảng
Array.prototype.push.call(arrayLike, "c"); // arrayLike trở thành {0: "a", 1: "b", 2: "c", length: 3}

2. Thực hiện kế thừa (chuỗi constructor)

Gọi constructor cha trong constructor con:

function Parent(name) {
  this.name = name;
}
function Child(name, age) {
  Parent.call(this, name); // Kế thừa thuộc tính từ Parent
  this.age = age;
}

3. Xử lý mảng tham số

Giải nén mảng thành danh sách tham số (thông dụng trước ES6):

const numbers = [1, 3, 5, 2];
const max = Math.max.apply(null, numbers); // In ra 5
// Thay thế ES6: Math.max(...numbers)

4. Thao tác với đối tượng giống mảng

Chuyển đổi đối tượng giống mảng (như arguments, danh sách nút DOM) thành mảng thực sự:

function example() {
  const args = Array.prototype.slice.call(arguments); // Chuyển thành mảng
  // Thay thế ES6: const args = Array.from(arguments);
}

5. Ràng buộc ngữ cảnh hàm rõ ràng

Đảm bảo this trong hàm callback hoặc xử lý sự kiện được ràng buộc đúng:

const handler = {
  message: "Hello",
  handleClick() { console.log(this.message); }
};
button.addEventListener("click", () => {
  handler.handleClick.call(handler); // Ràng buộc `this` đến handler
});
// Cách viết ngắn gọn hơn: sử dụng bind()
button.addEventListener("click", handler.handleClick.bind(handler));

Tóm tắt

  • Ưu tiên sử dụng call: Khi tham số rõ ràng và số lượng cố định.
  • Ưu tiên sử dụng apply: Khi tham số đã tồn tại trong mảng hoặc số lượng không xác định.
  • Thay thế ES6+: Toán tử giải nén (...) và Array.from() giảm thiểu việc sử dụng apply, nhưng call/apply vẫn có giá trị trong các trường hợp yêu cầu tương thích cao hoặc đặc biệt.

Thẻ: JavaScript call apply this context binding

Đăng vào ngày 24 tháng 6 lúc 02:43