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.getName
cho đối tượngperson
. - Thứ hai, truyền hàm được gán
f
với giá trịthis
được gán cho đối tượngperson
và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ượngflyer
làm đối số đầu tiên và20
là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.