Sử Dụng Bind, Call và Apply Như Thế Nào Trong Javascript

Giới thiệu


Ba hàm bind, call và apply là các prototype của Function nên chỉ có Function mới có thể gọi được 3 hàm này. Sở dĩ, một Function có thể gọi Function khác vì trong JavaScript, Function cũng là một loại Object, mà đã là Object thì sẽ có prototype, hay nói cách khác là gọi được phương thức của nó.


Lưu ý:

  • "bind", "call", "apply" dùng để thiết lập ngữ cảnh ngữ cảnh con trỏ this
  • "bind" không tồn tại trong arrow function ()=> {} (vì arrow function không có context)

Video Học Lập trình


Nguồn Yotube - Akshay Saini



Bind()


Bind() cho phép chúng ta dễ dàng thiết lập một đối tượng cụ thể sẽ bị ràng buộc này khi một chức năng hoặc phương pháp được gọi.


Cú pháp: func.bind(thisArg[, arg1[, arg2[, ...argN]]])


  • thisArg: Giá trị của this được đưa ra để gọi hàm. Giá trị bị bỏ qua nếu hàm liên kết được xây dựng bằng toán tử new. Khi sử dụng bind để tạo ra một hàm dưới dạng callback trong hàm setTimeout, bất kỳ giá trị nào sơ khai được truyền dưới dạng thisArg sẽ được chuyển đổi thành đối tượng.
  • arg1, arg2, ...argN: Các đối số cho hàm.
const teacher = {
  firstName: "Thư",
  lastName: "Nguyễn",
  getFullname: function () {
    console.log(`${this.firstName} ${this.lastName}`);
  },
};

teacher.getFullname(); //Thư Nguyễn

const callGetFullname = teacher.getFullname;
callGetFullname(); // undefined  undefined
-> this ở đây sẽ là đối tượng window

const student = {
  firstName: "Nam",
  lastName: "Hoài",
};

const useBindForStudent = teacher.getFullname.bind(student);
useBindForStudent(); // Nam Hoài
-> bind sẽ ràng buộc this cho student


  • Không chỉ bind được giá trị this, bind còn bind được các tham số truyền vào cho hàm nữa. Do đó, Bind còn được dùng để viết partial function.
  • Nói một cách đơn giản, partial function tức là tạo ra 1 function mới từ 1 function cũ bằng cách gán mặc định một số tham số cho function cũ đó.


Ví dụ: Mình có một hàm log đơn giản có 3 tham số


function log(level, time, message) {
 console.log(level + ' - ' + time + ': ' + message);
}


Giả sử mình muốn tạo một hàm log khác, ghi lại các log error của hôm nay, mình có thể viết một hàm mới dựa theo hàm log cũ:


function log(level, time, message) {
 console.log(level + ' - ' + time + ': ' + message);
}

function logErrToday(message) {
 log("Error", "Today", message);
}

logErrToday("Server die."); // Error - Today: Server die.


Thay vì viết như thế, mình có thể viết đơn giản hơn bằng các dùng bind. Ở đây log là function cũ, logErrToday là function mới, được tạo ra bằng cách gán mặc định 2 tham số level và time.


function log(level, time, message) {
 console.log(level + ' - ' + time + ': ' + message);
}

// Không có this nên set this là null
// Set mặc định 2 tham số level và time
var logErrToday = log.bind(null, 'Error', 'Today');

// Hàm này tương ứng với log('Error', 'Today', 'Server die.')
logErrToday("Server die."); 
// Error - Today: Server die.


Call()


Call gọi một hàm với giá trị của this và các đối số riêng lẻ.


Cú pháp: function.call(thisArg, arg1, arg2, ...)


Trong đó:

  • thisArg: Giá trị của this được đưa ra để gọi hàm. Lưu ý rằng this có thể không phải là giá trị thực tế được thấy bởi phương thức: Nếu phương thức là một hàm trong non-strict mode, giá trị null và undefined sẽ được thay thế với global object và các giá trị sơ khai (primitive) sẽ được chuyển thành các đối tượng (objects).
  • arg1, arg2, ...argN: Các đối số cho hàm.

Các bạn hãy theo dõi các ví dụ dưới để hiểu rõ về cách sử dụng hàm call trong javascript nhé.


Ví dụ 1: dùng call để thay đổi ngữ cảnh con trỏ this


const person = {
  fullName: function() {
    return this.firstName + " " + this.lastName;
  }
}
const person1 = {
  firstName:"John",
  lastName: "Doe"
}
const person2 = {
  firstName:"Mary",
  lastName: "Doe"
}


person.fullName.call(person1); // John Doe
person.fulllname.call(person2): // Mary Doe


Ví dụ 2: Sử dung hàm call để gọi hàm và đưa ra một giá trị cho đối tượng 'this'


function greet() {
 var reply = [this.person, 'Is An Awesome', this.role].join(' ');
 console.log(reply);
}

var x = {
 person: 'Khoa Nguyen', role: 'Javascript Developer'
};

greet.call(x); // Khoa Nguyen Is An Awesome Javascript Developer


Trong ví dụ dưới trên khi chúng ta gọi hàm greet , giá trị của this trong hàm greet chính là đối tượng x.


Ví dụ 3: Sử dung call để chain constructors cho một đối tượng


Bạn có thể sử dụng hàm call để chain constructors cho một đối tượng giống như trong Java. Trong ví dụ dưới đây, hàm khởi tại của đối tượng Product được định nghĩa với 2 tham số, name và price. Hai hàm Food và Toy gọi Product với tham số this , name và price. Product khởi tạo thuộc tính name và price, cả 2 hàm này định nghĩa category.


function Product(name, price) {
 this.name = name;
 this.price = price;
}

function Food(name, price) {
 Product.call(this, name, price);
 this.category = 'food';
}

function Toy(name, price) {
 Product.call(this, name, price);
 this.category = 'toy';
}

var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);


Apply()


Apply gọi một hàm với giá trị của this và các đối số được truyền vào dưới dạng mảng.


Cú pháp:

func.apply(thisArg, [ argsArray])


  • thisArg: Giá trị của this được đưa ra để gọi hàm. Lưu ý rằng this có thể không phải là giá trị thực tế được thấy bởi phương thức: Nếu phương thức là một hàm trong non-strict mode, giá trị null và undefined sẽ được thay thế với global object và các giá trị sơ khai (primitive) sẽ được chuyển thành các đối tượng (objects).
  • argsArray: Một mảng chỉ định các đối số cho hàm, hoặc null hoặc undefined nếu không có đối số nào được cung cấp.

Các bạn hãy theo dõi các ví dụ dưới để hiểu rõ về cách sử dụng hàm apply trong javascript nhé.


Ví dụ 1: Sử dụng hàm apply với built-in functions


const person = {
  fullName: function() {
    return this.firstName + " " + this.lastName;
  }
}

const person1 = {
  firstName: "Mary",
  lastName: "Doe"
}

// This will return "Mary Doe":
person.fullName.apply(person1);


Ví dụ 2: Sử dụng hàm apply để nối 1 mảng vào 1 mảng khác


const array = ['a', 'b'];
const elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]


Ví dụ 3: Sử dung apply để chain constructors


Bạn có thể sử dụng hàm call để chain constructors cho một đối tượng giống như trong Java.


Trong ví dụ dưới đây chúng ta sẽ tạo ra một global Function method gọi là construct, phương thức này sẽ cho phép bạn sử dụng một đối tượng giống mảng với một hàm tạo thay vì một danh sách đối số.


Function.prototype.construct = function(aArgs) {
 let oNew = Object.create(this.prototype);
 this.apply(oNew, aArgs);
 return oNew;
};


Phân biệt Call(), Apply(), Bind()


  • Nhìn chung, hàm call và apply là gần giống nhau. Chúng đều gọi hàm trực tiếp. Chỉ khác ở cách truyền tham số vào (với call thì đối số phân cách bởi dấu phẩy và với apply thì đối số cho bởi mảng array)
  • 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à trả về một hàm mới. Sau đó, bạn có thể sử dụng hàm mới này. Về cách truyền tham số vào thì hàm bind giống với hàm call.


Tổng kết


Bằng việc sử dụng bind, call và aplly ta có thể thay đổi được ngữ cảnh thực thi (phạm vi chứa hàm) để sử dụng một hàm với công dụng đa năng hơn như thực thi cho một đối tượng, phạm vi khác khác giúp ta có thể tận dụng tối đa mã nguồn được đã tạo ra, hay tạo shortcut cho hàm, linh hoạt hơn tham số đầu vào.


Với call và apply, chúng ta sử dụng để thực thi hàm đó luôn khi gọi, còn với bind ta có thể thực thi hàm đó nhiều lần sau khi đã được buộc (bind) với một ngữ cảnh nhất định.

quản trị viên

Chia sẻ bài viết:

Tin tức liên quan

Muốn học React JS trong vòng 3 tháng thì 8 điều cơ bản sau phải biết đầu tiên

Muốn học React JS trong vòng 3 tháng thì 8 điều cơ bản sau phải biết đầu tiên

Lập trình React JS nghe có vẻ cao siêu và tôi chắc chắn rằng sẽ có nhiều cơ hội trong tương lai của bạn. Nhưng để học React JS một cách khôn khéo và nhanh chóng hiểu được những cú pháp trong React JS là không phải ai cũng có thể làm dược trong một thời gian ngắn. Và nếu bạn đọc được bài viết này thì chỉ 3 tháng thôi bạn sẽ có thể vươn lên một bậc rồi.

Gửi mail trong nodejs với Nodemailer đơn giản trong lập trình Javascript

Gửi mail trong nodejs với Nodemailer đơn giản trong lập trình Javascript

Trong bài viết này mình hướng dẫn chi tiết gửi mail thông qua Nodemailer đơn giản nhất, việc gửi email không chỉ đơn giản là gửi văn bản thông điệp nữa. Email đã trở thành một phần quan trọng của ứng dụng và dịch vụ trực tuyến, từ việc xác nhận tài khoản, thông báo sự kiện cho đến marketing. Trong bài viết này, chúng ta sẽ khám phá cách sử dụng thư viện Nodemailer trong Node.js để dễ dàng gửi email từ ứng dụng của bạn.

Xem thêm...