Sự khác biệt giữa apply() và call() trong JavaScript

Mỗi hàm trong JavaScript đều sở hữu hai phương thức: apply()call(), cho phép thay đổi ngữ cảnh this khi gọi hàm. Cú pháp của chúng như sau:

/* apply() */
func.apply(thisArg, [argsArray])

/* call() */
func.call(thisArg, arg1, arg2, ..., argN)

Cách hoạt động chung

Cả hai đều dùng để gọi một hàm với ngữ cảnh this được chỉ định rõ ràng — tức là "mượn" phương thức từ đối tượng này để thực thi trên đối tượng khác.

Khác biệt chính

  • apply(): Nhận tối đa hai tham số — thisArg và một mảng (hoặc đối tượng giống mảng) chứa các đối số cần truyền vào hàm. Nếu không truyền mảng, sẽ gây lỗi TypeError.
  • call(): Cũng nhận thisArg làm tham số đầu tiên, nhưng các đối số tiếp theo được truyền riêng lẻ, không gói trong mảng.

Ví dụ minh họa

1. Gọi hàm với ngữ cảnh khác

function sum(x, y) {
  return x + y;
}

function diff(x, y) {
  return x - y;
}

let result1 = sum.apply(diff, [5, 3]);  // 8
let result2 = diff.call(sum, 5, 3);     // 2

2. Kế thừa đơn giản

function LivingBeing(name) {
  this.name = name;
  this.introduce = function() {
    console.log("Tôi là " + this.name);
  };
}

function Bird(name) {
  LivingBeing.call(this, name);  // hoặc .apply(this, [name])
}

let sparrow = new Bird("Chim sẻ");
sparrow.introduce(); // "Tôi là Chim sẻ"

3. Kế thừa nhiều lớp

function Adder() {
  this.add = function(a, b) { return a + b; };
}

function Subtractor() {
  this.subtract = function(a, b) { return a - b; };
}

function Calculator() {
  Adder.apply(this);
  Subtractor.apply(this);
}

let calc = new Calculator();
console.log(calc.add(10, 5));      // 15
console.log(calc.subtract(10, 5));  // 5

Mẹo sử dụng apply() linh hoạt

Tìm giá trị lớn nhất/nhỏ nhất trong mảng

let numbers = [3, 7, 2, 9, 1];
let max = Math.max.apply(null, numbers); // 9
let min = Math.min.apply(null, numbers); // 1

Dùng nullMath.max là hàm tĩnh, không cần this. apply giúp "giải nén" mảng thành danh sách tham số.

Gộp hai mảng

let arrA = [1, 2, 3];
let arrB = [4, 5, 6];
Array.prototype.push.apply(arrA, arrB);
// arrA giờ là [1, 2, 3, 4, 5, 6]

Ở đây, arrA "mượn" phương thức push và truyền toàn bộ phần tử của arrB như các tham số riêng lẻ nhờ apply.

Khi nào nên dùng?

Dùng apply khi bạn có dữ liệu dạng mảng nhưng hàm đích lại yêu cầu tham số rời rạc. Dùng call khi bạn biết trước số lượng và giá trị các đối số cần truyền.

Thẻ: JavaScript apply call this-binding function-context

Đăng vào ngày 27 tháng 5 lúc 23:33