Call, Bind và Apply trong Javascript

Reference from: https://hpphat.wordpress.com/2016/09/07/call-bind-va-apply-trong-javascript/

Mục tiêu của bài viết là để làm rõ hơn về 1 chủ đề mà mình nghĩ là chuyên sâu trong JS (và mình cũng đang có hứng thú nên viết để mọi người cùng chia sẻ).

Nguồn tham khảo và dịch:

How To Use .call(), .apply() and .bind() In Javascript

Apply vs. Call vs. Bind in JavaScript

MDN – Apply

MDN – Call

MDN – Bind

Trong Javascript, mọi hàm đều tồn tại 1 con trỏ this (cái này nó giống C# nhỉ) để chứa đựng ngữ cảnh (context) của caller (người gọi). Về chi tiết hơn của con trỏ this thì mình chưa bàn ở đây. Mục tiêu chỉ là phân biệt 3 hàm call(), bind() và apply() trong JS????.

Call()

Call là hàm đơn giản, dễ hiểu nhất trong bộ 3 khó nhằn này. Mục tiêu của nó chỉ là mình thực hiện lời gọi hàm như thông thường, nhưng điều khác biệt ở đây so với những lời gọi hàm thông thường là mình có thể xác định ngữ cảnh bên trong hàm được gọi (thay vì mặc định là caller hiện hành).

Cú pháp:

bandicam 2016-09-07 23-26-58-284.jpg

Ví dụ:

Ta có khai báo hàm như sau:

bandicam 2016-09-07 23-19-58-642.jpg

 

Như trên ví dụ trên, hàm call đã thay đổi ngữ cảnh chứa trong con trỏ this bằng giá trị mà ta truyền vào trong tham số thứ nhất. Điều này sẽ giúp ta viết được những đoạn code mang tính phổ quát hơn và dễ dàng sử dụng lại được.

Apply()

Cú pháp của hàm Apply()

bandicam 2016-09-07 23-25-58-693.jpg

Apply là 1 hàm tương tự nhưng call(). Điểm khác nhau chủ yếu là với call(), ta sẽ truyền các tham số lần lượt vào trong hàm (nghĩa là arg0 là ngữ cảnh, arg1 là tham số đầu tiên mà hàm sẽ nhận được, arg2 là tham số thứ hai mà hàm nhận được…). Với apply(), ta sẽ truyền mảng các tham sốthông qua tham số thứ hai của hàm apply.

 

Về tính năng, apply() hoạt động tương tự như call()

Ví dụ:

bandicam 2016-09-07 23-28-39-524.jpg

Ngẫm đến đây, ắt hẳn nhiều bạn vẫn dùng hàm [].push.apply() để nối 2 mảng con lại với nhau????.

Ứng dụng của Call & Apply

  • Sử dụng Apply trpmg một số hàm cho phép truyền vô tận các đối số (VD: Array.push, Math.max, Math.min) giúp kéo giảm các vòng lặp????.
  • Sử dụng Call để đơn giản thay đổi ngữ cảnh của hàm được gọi, mình cũng ít xài cái này nên vẫn chưa thấy nhiều ưu thế vượt trội hơn cái apply. Hiển nhiên, tuỳ trường hợp thuận tiện mà ta nên cân nhắc giữa 2 anh này????.

Bind()

Bind là function của JS có chức năng tạo ra một hàm mới có xử lý hoàn toàn giống với hàm đã cho và có ngữ cảnh có thể thay đổi được cũng như các tham số mặc định được xác định trước. Việc thiết lập các tham số ban đầu làm mình liên tưởng đến partial function trong JS mà lodash có implement trong hàm _.partial(). Hàm partial có nghĩa là mình sẽ điền các tham số mặc định (từ trái sang) và khi gọi hàm đó, mình truyền thêm 1 mớ tham số vào thì các tham số đó sẽ điền tiếp nối vào sau. (Xem_.partial để biét thêm chi tiết :D).

Cú pháp của ẻm:

bandicam 2016-09-07 23-39-00-466.jpg

Ví dụ:

bandicam 2016-09-07 23-39-40-938.jpg

Trong ví dụ trên, hàm say() có sử dụng con trỏ this và tuỳ theo ngữ cảnh được truyền vào trong lời khai báo ở dòng 8 và dòng 9 mà các hàm trã về (sayHelloJon và sayHelloKelly) sẽ có ngữ cảnh khác nhau (và sẽ không còn là ngữ cảnh mạc đinh của caller).

Ứng dụng của Bind

  • Thay đổi ngữ cảnh của một số hàm xử lý sự kiện hoặc các hàm setTimeout, setInterval …
  • Áp dụng vào partial function.
  •  Và còn vài cái khác mà mình chưa xài nên k dám bình loạn????

438 total views, 1 views today

Trả lời