Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.
Nếu bạn đã từng sử dụng đối tượng this
trong Javascript, chắc hẳn bạn đã gặp một số khó khăn khi sử dụng, đặc biệt là trong trường hợp sử dụng trong những hàm và đối tượng người tiêu dùng. Tuy nhiên, khi bạn thành thạo rồi, bạn sẽ nhận thấy đối tượng this
rất hữu ích và thú vị.
Table of Contents
1. Đặt vấn đề với this
Đối tượng this
thường gây rất nhiều khó khăn cho người học Javascript, đặc biệt là khi bạn sử dụng hàm closure. Tuy nhiên, khi bạn nắm vững nguyên tắc, bạn sẽ nhận ra rằng đối tượng this
thực sự hữu ích và thú vị.
Xét ví dụ sau:
var blog = {
domain : "freetuts.net",
author : "Nguyễn Văn Cường",
showWebsite : function (callbackFunction){
callbackFunction();
},
render : function(){
this.showWebsite(function(){
console.log(this); // là đối tượng window
console.log(this.domain); // thuộc tính domain không tồn tại
console.log(this.author); // thuộc tính author không tồn tại
});
}
};
blog.render();
Trong ví dụ này, chúng ta gặp lỗi vì biến this
không phải là đối tượng blog
, mà đó là đối tượng window
. Do đó, hai thuộc tính domain
và author
sẽ không tồn tại. Bạn có thể hiểu ý đồ của chương trình là gọi tới hai thuộc tính domain
và author
, nhưng theo nguyên tắc của hàm closure, đối tượng this
là một phạm vi hoàn toàn khác (xem hình).
Trong hình trên, phạm vi 2 đang nằm trong hàm thuộc đối tượng blog
, do đó this
lúc này chính là blog
. Còn trong phạm vi 1 là hàm closure, nên đối tượng this
đương nhiên chính là hàm closure.
Để giải quyết vấn đề này, ta có thể khai báo một biến đại diện cho đối tượng this
, sau đó sử dụng biến đó trong hàm closure.
var blog = {
domain : "freetuts.net",
author : "Nguyễn Văn Cường",
showWebsite : function (callbackFunction){
callbackFunction();
},
render : function(){
var _self = this;
this.showWebsite(function(){
console.log(_self); // là đối tượng this
console.log(_self.domain); // ok
console.log(_self.author); // ok
});
}
};
blog.render();
Như vậy, khi ta khai báo biến _self
, vấn đề đã được giải quyết. Tuy nhiên, phương pháp này chỉ dành cho những người chưa biết đến hàm bind()
.
2. Khắc phục với hàm bind trong Javascript
Ngoài cách xử lý thông thường, trong ES5 còn cung cấp hàm bind()
dùng để gán dữ liệu vào đối tượng this
của hàm đang sử dụng. Trở lại với ví dụ trên, chúng ta sẽ sử dụng hàm bind()
như sau:
var blog = {
domain : "freetuts.net",
author : "Nguyễn Văn Cường",
showWebsite : function (callbackFunction){
callbackFunction();
},
render : function(){
this.showWebsite(function(){
console.log(this); // là đối tượng this
console.log(this.domain); // ok
console.log(this.author); // ok
}.bind(this));
}
};
blog.render();
Hãy chạy thử để xem kết quả, và như vậy, hàm bind()
sẽ đưa dữ liệu từ bên ngoài vào trong hàm.
Bây giờ, chúng ta cùng thử bind một kiểu dữ liệu khác xem sao.
var blog = {
showWebsite : function (callbackFunction){
callbackFunction();
},
render : function(){
this.showWebsite(function(args){
console.log(this); // Đối tượng này chính là mảng truyền vào
}.bind(["freetuts.net", "[email protected]"]));
}
};
blog.render();
Khi chạy, bạn sẽ thấy hiệu quả như sau:
Như vậy, khi bạn truyền bất kỳ một loại dữ liệu nào trong tham số của hàm bind()
, đối tượng this
sẽ nhận chính dữ liệu đó.
3. Lời kết
Hàm bind()
được bổ trợ vào core của Javascript kể từ phiên bản ES5. Đây là một cách khắc phục điểm yếu kém sử dụng this
trong Javascript. Nếu bạn đã từng sử dụng ES6, cách khắc phục khác là sử dụng arrow function. Chúc bạn học tốt!
Source: https://wikifin.net