Phân biệt call(), apply() và bind() trong JavaScript
1. Phân biệt các cách gọi hàm JavaScript: call() và apply() vs bind()
– Mục đích chính của call() và apply() là set context của this
bên trong một hàm bất kể hàm đó đang được gọi trong phạm vi toàn cục (global scope) hay là phương thức của đối tượng (object’s method).
– Bạn có thể truyền một đối tượng như là một tham số của call() và apply(). Cả hai có thể được sử dụng để gọi một phương thức đối tượng (object method) với tham số (argument) là một đối tượng khác.
Xem thêm:
– Gọi hàm với phương thức call() trong JavaScript.
– Gọi hàm với phương thức apply() trong JavaScript.
– Hai hàm call() và apply() có công dụng giống nhau, chúng đều gọi hàm trực tiếp, tuy nhiên về cú pháp thì có một chút khác biệt như sau:
- Tham số đầu tiên của hàm call() là đối tượng
this
, tiếp theo chính là các tham số của hàm cần gọi. - Tham số đầu tiên của hàm apply() là đối tượng
this
, tham số tiếp theo là một mảng chứa các tham số của hàm cần gọi.
– Như vậy sự khác biệt ở đây chính là tham số truyền vào: call sẽ truyền lần lượt các tham số, còn apply sẽ truyền một mảng các tham số.
Ví dụ:
[code language=”javascript”]var sayHello = function(message, name){alert(message + name);
};
sayHello.call(sayHello, ‘Welcome to ‘, ‘Minh Hoàng Blog!’);
sayHello.apply(sayHello, [‘Welcome to ‘, ‘Minh Hoàng Blog!’]);[/code]
Try it »
Xem thêm: Từ khóa this trong JavaScript.
– Hàm bind() thì hơi khác hơn một chút. Hàm này không gọi hàm trực tiếp mà nó sẽ trả về một hàm mới. Và bạn có thể sử dụng hàm số mới này sau. Về cách truyền tham số vào thì nó giống với hàm call().
Ví dụ:
[code language=”javascript”]var person1 = {firstName: ‘Steve’, lastName: ‘Jobs’};var person2 = {firstName: ‘Bill’, lastName: ‘Gates’};
function sayHello(msg1, msg2){
console.log(msg1 + ‘,’ + msg2 + ‘ ‘ + this.firstName + ‘ ‘ + this.lastName);
}
// call() method
sayHello.call(person1, ‘Hello’, ‘ Good morning’); // Hello, Good morning Steve Jobs
sayHello.call(person2, ‘Hello’, ‘ Good morning’); // Hello, Good morning Bill Gates
// bind() method
var sayHelloSteve = sayHello.bind(person1, ‘Hello’, ‘Good morning’);
var sayHelloBill = sayHello.bind(person2, ‘Hello’, ‘Good morning’);
sayHelloSteve(); // Hello, Good morning Steve Jobs
sayHelloBill(); // Hello, Good morning Bill Gates[/code]
Try it »
2. Khi nào dùng call(), apply(), bind()?
- Sử dụng .bind() khi bạn muốn hàm đó sau này được gọi với một ngữ cảnh nhất định, hữu ích khi dùng trong các sự kiện (events).
- Sử dụng .call() hoặc .apply() khi bạn muốn gọi hàm ngay lập tức và sửa đổi ngữ cảnh (context).
Hàm call hay apply gọi hàm ngay lập tức, nhưng bind trả về một hàm với ngữ cảnh chính xác được thiết lập để gọi hàm ban đầu khi được thực thi sau này. Điều này cho phép bạn duy trì ngữ cảnh với các callbacks và events không đồng bộ (async).
Ví dụ:
[code language=”javascript”]function MyObject(element) {this.elm = element;
element.addEventListener(‘click’, this.onClick.bind(this), false);
};
MyObject.prototype.onClick = function(e) {
var t = this; // làm cái gì đó với [t]…
// nếu không có bind context của function này thì sẽ không phải là MyObject,
// instance mà bạn mong đợi.
};[/code]
Try it »
Ngoài ra, còn có nhiều thứ khác về bind(), bạn có thể đọc thêm về nó và xem việc thực hiện thực sự (real implementation) trên MDN: Function.prototype.bind() – JavaScript | MDN.