Call(), apply() và bind() trong JavaScript

Tram Ho

Khi học và thực hành với JavaScript, chắc hẳn đều khá quen thuộc với ít nhất một trong ba phương thức all(), bind() và apply(). Có thể chúng ta không thường xuyên sử dụng các phương thức này, tuy nhiên nó lại khá phổ biến trong bất kì cuộc phỏng vấn nào về JavaScript.

Trong JavaScript, functions (hàm) là các objects (đối tượng). Objects có thể bao gồm các properties (thuộc tính) và methods (phương thức). Hầu hết với mọi function, chúng ta đều có thể nhận được ba phương thức này.


Nhưng trước khi bắt đầu, hãy xem các ví dụ sau:
Khi thực thi một function, điều này sẽ được xác định bởi cách mà một function được gọi (runtime binding).

  • Trong một method (phương thức): đề cập đối owner object (đối tượng chủ sở hữu).
  • Trong một function (sloppy mode – chế độ không nghiêm ngặt): đề cập đến global object (đối tượng toàn cục).
  • Trong một function (strict mode – chế độ nghiêm ngặt): không xác định.

Giờ thì bắt đầu nào…

call()

Theo định nghĩa:

Phương thức call() gọi một function với value đã sẵn có và các argument (đối số) được cung cấp riêng lẻ. Nói một cách dễ hiểu, quyết định cái gì thì sẽ là cái đó – ở trong function khi ta gọi nó.

Hãy xem một ví dụ cơ bản để hiểu vấn đề này.

Ta có một function personIntro() đang cố gằng truy nhập vào console của firstName và lastName. Chúng ta có ba outputs như sau:

  • Nếu không sử dụng phương thức call(), vì thế phương thức này sẽ mặc định tham chiếu đến window object. Window object sẽ không có bất kì thuộc tính nào là firstName hay lastName. Do đó, kết quả trả về là không xác định và không xác định (undefined & undefined).
  • Nếu sử dụng call() và truyền một object có properties là required, ở đây là person. Do đó, kết quả trả về sẽ là Sanjeev Sharma.
  • Giống như outputs trên, chỉ là mô tả thêm về cách call() hoạt động.

Cũng có thể pass các đối số bổ sung trong call() như sau:

bind()

Theo định nghĩa:

Phương thức bind() tạo ra một function mới, và khi được gọi, keyword (từ khoá) của nó sẽ được set một value được cung cấp, với một chuỗi các đối số cho trước bất kì đối số nào được cung cấp khi function được gọi.

Rất tiếc, quá nhiều thông tin để xử lý cùng một lúc, vì vậy nếu đã hiểu call(), hãy sử dụng kiến thức đó để hiểu bind().

Chúng ta lại tạo ra một function getPerson(). Giờ thì có hai outputs:

  • Sử dụng call() và pass { state: ‘California’ } (đối số đầu tiên) làm đối số. Đối số thứ hai sẽ là person.
  • Cố gắng để output sẽ giống như khi sử dụng bind(). Với việc sử dụng bind(), chúng ta có thể liên kết giá trị này với một funtion và nhận lại một function khác. Trong trường hợp trên, chúng ta liên kết nó với { state: ‘California’ } và lữu trữ được function trả về trong personFromCalifornia. Giờ khi khi gọi personFromCalifornia, chỉ cần truyền argument là person. Nó sẽ có một giá trị như này.

Chỉ cần gọi lại một function tương tự với một argument person khác.

Vậy sự khác biệt giữa call() và bind() ở đây là gì?

  • call() được get invoked ngay lập tức trong khi bind() trả về một function mà có thể invoke sau.
  • call() nhận các agrument bổ sung nhưng bind() thì không vậy.
  • call() không tạo ra bản sao của function, không giống như bind().

apply()

Theo định nghĩa:

Phương thức apply() gọi một function với value đã cho, và các argument đã được cung cấp dưới dạng một array (mảng) (hoặc một đối tượng giống mảng).

Về cơ bản là giống hệt như call(), chỉ có một sự khác biệt nhỏ.

call() nhận đối số riêng lẻ nhưng apply() thì nhận dưới dạng một mảng. Chỉ có vậy thôi.

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo