Javascript: Nhân vật bí ẩn và đáng sợ prototype!

Prototype là một khái niệm mà bạn bè hỏi tôi khá nhiều lần và câu trả lời của tôi cũng rất mơ hồ và họ cũng gật gù nhưng tôi hiểu có lẽ họ cũng chưa hài lòng lắm …

Mọi thứ trong javascript đều là Object: string(String), number(Number), date(Date), function(Function), … và cái prototype gắn liền với khái niệm Object này. Theo tôi, prototype được hiểu như là khuôn hoặc là cha của một object.

Thử tưởng tượng nhé, ta có một string:

const myString = 'Hello World';

Sau đó, chúng ta sử dụng một method của string như sau:

const isIncludeHello = myString.includes('Hello');

Bam!! Tại sao biến myString lại có được hàm includes. Vì khi chúng ta console.log myString, chúng ta không thấy bất cứ method nào trong myString. Có phải thực sự huyền bí không?

Prototype đã đến bên ta và để giải thích sự kì lạ này. Khi ta khai báo một string thì javascript engine sẽ tự động thêm một Object kì lạ có tên là __proto__  vào mỗi object, như ví dụ ở đây là biến myString. Bam !! Sau khi add __proto__ vào myString thì chuyện gì sẽ xảy ra tiếp theo.

Khi bạn gọi myString.includes(‘Hello’), javascript sẽ tiến hành dò tìm method includes trong chính đối tượng đó. Sau đó nếu không có nó sẽ tìm tiếp đến __proto__ object(cha của myString). Và nếu như trong object __proto__ lại có __proto__ , thì cứ như thế nó sẽ tìm mãi đến khi nào không còn __proto__ nữa thì thôi. Khái niệm này gọi là Prototype Chain trong javascript.

Obj có một property là prop1. Khi truy xuất obj.prop1 ra kết quả là điều bình thường phải không nào. Nhưng khi truy xuất obj.prop2, vì nội tại obj không có property này nên nó sẽ tìm tiếp lên __proto__ thì thấy trong này tồn tại. Cứ như thế giải thích cho obj.prop3. __proto__ gồm nhiều cấp khác nhau và chúng tạo nên một mắc xích nên được gọi là chain.

Chúng ta có một cách khác để khai báo biến myString theo cách OOP như sau:

const myString = new String('Hello World');
console.log(myString);

Bam!! Bạn xem kết quả nhé:

Chúng ta thấy có một Object là __proto__ đúng không? Đó là cách prototype hoạt động. Chúng ta cùng xem prototype của String nhé:

Bên trái là __proto__ của myString và bên phải là prototype của String. The same!!! Javascript đã copy toàn bộ prototype của String cho __proto__ của myString. Đó cũng là cách mà thừa kế trong javascript hoạt động. Những object thừa kế thông qua prototype. Ở đây __proto__ là cha của object myString.

Thôi hiểu tới đây thôi nhé, bài kế chúng ta bàn về thừa kế(inheritance) trong javascript để anh em thấy __proto__ nó dị như thế nào.

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *