Trong quá tình làm việc với Javascript thì mình thấy từ khóa this đã gây không biết bao nhiêu phiền toái, không chỉ phiền cho các bạn còn non kinh nghiệm mà các bạn già kinh nghiệm đôi lúc không để ý cũng bị nó hành một cách tội nghiệp. Trước đây mình cũng từng lâm vào tình cảnh không biết lỗi do đâu, chỉ khi debug từng step mới nhận ra là do đặt this sai chỗ. Ok, vậy bây giờ mình sẽ bàn một chút về từ khóa này nhé.
1. Từ khóa this trong Function
Trong bài ba cách tạo class mình có sử dụng từ khóa this để gán các thuộc tính và phương thức cho đối tượng. Mình gọi là thuộc tính và phương thức vì đang suy diễn theo ý tưởng Javascript có thể lập trình hướng đối tượng, vì vậy bạn đừng ý kiến gì ở sự suy diễn này nhé.
Xét ví dụ sau:
1 2 3 4 5 6 7 8 9 10 11 | function Student() { this .name = '; this.age = ' ; this .showInfo = function () { console.log( this .name); console.log( this .age); }; } |
Trong đoạn code trên thì từ khóa this chính là function hiện tại (hàm student), và trong trường hợp này ta có thể ví hàm student là một đối tượng student = từ khóa this chính là đối tượng student. Nếu bạn để ý kĩ hơn thì trong hàm showInfo mình có sử dụng từ khóa this để gọi đến các phương thức và thuộc tính của đối tượng Student.
Bạn hãy xem cách sử dụng đối tượng Student như sau.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function Student() { this .name = '; this.age = ' ; this .showInfo = function () { console.log( this .name); console.log( this .age); }; } // Khởi tạo đối tượng var student = new Student(); // Gán giá trị cho các thuộc tính student.name = 'Nguyễn Văn Cường - code24h.com' ; student.age = '27' ; // Hiển thị thông tin student.showInfo(); |
Chạy đoạn code này nên bạn sẽ nhận được kết quả như hình dưới đây.
Như vậy hàm showInfo() đã hiển thị đúng thông tin mà ta đã gán. Bây giờ bạn sửa lại đoạn code trên như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | function Student() { this .name = '; this.age = ' ; // Log1 console.log( this ); this .showInfo = function () { // Log2 console.log( this ); }; } // Khởi tạo đối tượng var student = new Student(); // Gán giá trị cho các thuộc tính student.name = 'Nguyễn Văn Cường - code24h.com' ; student.age = '27' ; // Hiển thị thông tin student.showInfo(); |
Trong đoạn code này mình đã đánh dấu hai vị trí Log1 và Log2. Khi chạy lên kết quả sẽ in ra Log1 trước với nội dung rỗng và tiếp theo là Log2 với nội dung là dữ liệu mà ta đã gán. Như vậy bản chất cả hai từ khóa this ở hai vị trí đó đều chính là đối tượng Student (xem hình dưới đây).
Mọi thứ vẫn ổn phải không các bạn? Nếu vậy thì bạn hãy tiếp tục bạn hãy thử chạy đoạn code sau và đoán điều gì sẽ xảy ra nhé.
1 2 3 4 5 6 7 | setTimeout( function (){ // Log1 console.log( this ); }, 2000); // Log2 console.log( this ); |
Kết quả cả hai vị trí Log1 và Log2 đều trỏ tới đối tượng Window nên nó sẽ in ra giá trị giống nhau
2. Từ khóa this trong thẻ HTML
Có bao giờ gặp một đoạn mã HTML có chứa mã Javascript trong các thuộc tính sự kiện không? Nếu chưa thì bạn hãy xem ví dụ sau thật kỹ nhé.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | !DOCTYPE html html head titleTừ khóa this trong thẻ HTML/title meta charset= "UTF-8"
meta name= "viewport" content= "awidth=device-awidth, initial-scale=1.0"
script language= "javascript"
function showMessage(obj) { console.log(obj); } /script /head body input type= "button" id= "clickme" onclick= "showMessage(this)" value= "Click Me" / /body /html |
Bạn để ý trong button mình có một đoạn mã gọi tới hàm showMessage trong sự kiện click.
1 | input type= "button" id= "clickme" onclick= "showMessage(this)" value= "Click Me" / |
Câu hỏi đặt ra là tham số this mà ta đã truyền vào hàm đó là cái gì? Để trả lời thì bạn hãy xem nội dung của hàm showMessage nhé.
1 2 3 4 | function showMessage(obj) { console.log(obj); } |
Hàm này đã nhận một tham số obj, như vậy đối tượng this mà ta truyền vào lúc này chính là tham số obj. Cuối cùng đoạn code console.log(obj); sẽ in ra giá trị của tham số obj. (xem hình dưới đây).
Như vậy tham số this chính là thẻ HTML hiện tại. Đây là cách mà chúng ta hay dùng để lấy thông tin của thẻ HTML khi xảy ra sự kiện. Bây giờ bạn sửa lại nội dung của hàm showMessage như sau:
1 2 3 4 | function showMessage(obj) { alert(obj.value); } |
Đoạn code này sẽ in ra giá trị (value) của obj mà obj lúc này chính là thẻ button nên giá trị nó sẽ in ra là "Click Me". Bạn hãy chạy lại và click vào button để xem kết quả nhé.
3. Từ khóa this sự kiện lồng nhau
Trong phần này mình sẽ lấy một ví dụ được viết bằng jQuery.
1 2 3 4 5 6 7 8 9 10 | $( '#button' ).click( function (){ // This của #button console.log( this ); $( '#element' ).click( function (){ // This của #element console.log( this ); }); }); |
Trong ví dụ này đã gán cho thẻ #button một sự kiện click, khi click vào #button đó thì sẽ chạy một đoạn code gán tiếp một sự kiện click cho thẻ #element, và hai đoạn code console.log(this) ở hai vị trí đã in ra hai giá trị khác nhau hoàn toàn, đoạn thứ nhất this chính là #button và đoạn thứ hai this chính là #element.
4. Lời kết
Như vậy có thể coi từ khóa this là một con trỏ, nó sẽ trỏ đến đối tượng hiện tại hoặc thẻ HTML hiện tại đang xử lý. Trong thực tế chúng ta sử dụng từ khóa này rất nhiều nên bạn cần phải nắm vững để tránh những sai sót không đáng có.