JavaScript

Phân biệt call(), apply() và bind() trong JavaScript

Phân biệt call(), apply() và bind() trong JavaScript
Được viết bởi Minh Hoàng

Series lập trình JavaScript, ngôn ngữ lập trình linh động, thực thi phía client.

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()

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()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()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.

– Hai hàm call()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ụ:
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!']);
Try it »

– 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ụ:
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
Try it »
2. Khi nào dùng call(), apply(), bind()?

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 callbacksevents không đồng bộ (async).

Ví dụ:
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.
};
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.

Cảm ơn bạn đã theo dõi. Đừng ngần ngại hãy cùng thảo luận với chúng tôi!


Giới thiệu

Minh Hoàng

Xin chào, tôi là Hoàng Ngọc Minh, hiện đang làm BrSE, tại công ty Toyota, Nhật Bản. Những gì tôi viết trên blog này là những trải nghiệm thực tế tôi đã đúc rút ra được trong cuộc sống, quá trình học tập và làm việc. Các bài viết được biên tập một cách chi tiết, linh hoạt để giúp người đọc có thể tiếp cận một cách dễ dàng nhất. Hi vọng nó sẽ có ích hoặc mang lại một góc nhìn khác cho bạn[...]

Bình luận của bạn

avatar

Phân biệt call(), apply() và bind() trong JavaScript

by Minh Hoàng Time to read: 4 min
0