JavaScript: Phương thức bind()
Phương thức bind() của JavaScript
Giới thiệu
Phương thức bind() trả về một hàm mới, khi được gọi, có this được gán cho một giá trị cụ thể.
Cú pháp của phương thức bind() như sau:
fn.bind(thisArg[, arg1[, arg2[, ...]]])
Trong cú pháp này, phương thức bind() trả về một bản sao của hàm fn với giá trị this cụ thể (thisArg) và các tham số (arg1, arg2, …).
Không giống như các phương thức call() và apply(), phương thức bind() không thực thi hàm ngay lập tức. Nó chỉ trả về một phiên bản mới của hàm với this được gán cho đối số thisArg.
Sử dụng phương thức bind() trong JavaScript để gán hàm
Khi bạn truyền một phương thức của một đối tượng làm callback cho một hàm khác, this sẽ bị mất. Ví dụ:
let person = {
name: 'John Doe',
getName: function() {
console.log(this.name);
}
};
setTimeout(person.getName, 1000);
Output
undefined
Như bạn có thể thấy rõ từ đầu ra, person.getName() trả về undefined thay vì 'John Doe'.
Điều này là do setTimeout() nhận hàm person.getName tách biệt khỏi đối tượng person.
Câu lệnh:
setTimeout(person.getName, 1000);
có thể được viết lại như sau:
let f = person.getName; setTimeout(f, 1000); // mất ngữ cảnh của person
this bên trong hàm setTimeout() được gán cho đối tượng toàn cục trong chế độ không nghiêm ngặt và undefined trong chế độ nghiêm ngặt.
Do đó, khi callback person.getName được gọi, name không tồn tại trong đối tượng toàn cục, nó được gán là undefined.
Để khắc phục vấn đề, bạn có thể bọc lời gọi đến phương thức person.getName trong một hàm ẩn danh, như sau:
setTimeout(function () {
person.getName();
}, 1000);
Đoạn mã trên hoạt động vì nó lấy person từ phạm vi bên ngoài và sau đó gọi phương thức getName().
Hoặc bạn có thể sử dụng phương thức bind():
let f = person.getName.bind(person); setTimeout(f, 1000);
Trong đoạn mã này:
- Đầu tiên, gán phương thức
person.getNamecho đối tượngperson. - Thứ hai, truyền hàm được gán
fvới giá trịthisđược gán cho đối tượngpersonvào hàmsetTimeout()
Sử dụng bind() để mượn phương thức từ đối tượng khác
Giả sử bạn có đối tượng runner có phương thức run():
let runner = {
name: 'Runner',
run: function(speed) {
console.log(this.name + ' runs at ' + speed + ' mph.');
}
};
Và đối tượng flyer có phương thức fly():
let flyer = {
name: 'Flyer',
fly: function(speed) {
console.log(this.name + ' flies at ' + speed + ' mph.');
}
};
Nếu bạn muốn đối tượng flyer có thể chạy, bạn có thể sử dụng phương thức bind() để tạo hàm run() với this được gán cho đối tượng flyer:
let run = runner.run.bind(flyer, 20); run();
Trong câu lệnh này:
- Gọi phương thức
bind()của phương thứcrunner.run()và truyền vào đối tượngflyerlàm đối số đầu tiên và20làm đối số thứ hai. - Gọi hàm
run().
Output
Flyer runs at 20 mph.
Khả năng mượn một phương thức của một đối tượng mà không cần sao chép phương thức đó và duy trì nó ở hai nơi riêng biệt là rất mạnh mẽ trong JavaScript.
Tóm tắt
Phương thức bind() tạo ra một hàm mới mà khi được gọi, có this được gán cho một giá trị cung cấp. Phương thức bind() cho phép một đối tượng mượn phương thức từ đối tượng khác mà không cần sao chép phương thức đó. Điều này được gọi là mượn hàm trong JavaScript.