Prototype chain là gì? Cách sử dụng Prototype chain hiệu quả

332

Prototype chain là một khái niệm cốt lõi trong JavaScript nhưng không dễ để nắm vững được nhất là đối với các anh em lập trình viên mới học ngôn ngữ này. Hiểu được khái niệm này sẽ giúp bạn dễ dàng triển khai được cơ chế kế thừa trong lập trình hướng đối tượng bằng JS. Bài viết hôm nay chúng ta cùng nhau đi sâu vào khái niệm quan trọng này nhé.

Prototype là gì?

Trong JavaScript, ngoại trừ undefined thì toàn bộ các kiểu còn lại đều là object. Các kiểu dữ liệu nguyên thủy (primitive) như string, số, boolean lần lượt sẽ là các object dạng String, Number, Boolean. Mảng là một object dạng Array, hàm trong JS cũng được xem là một object dạng Function. Vậy ý nghĩa của khái niệm object “dạng” này hay “dạng” kìa là gì? Và làm sao chúng ta biết được 1 object được tạo ra với dạng nào? Để giải quyết vấn đề này thì JS tạo ra khái niệm Prototype.

Prototype là gì?

Nếu như với các ngôn ngữ OOP (hướng đối tượng), kiểu class-based giúp chúng ta xác định rõ một object được tạo ra thuộc vào một class nào, sẽ kế thừa những thuộc tính (properties) và phương thức (methods) nào; thì với JS, việc kế thừa sẽ thực hiện theo kiểu prototype-based. Tất cả các object trong JS đều có một Prototype và các object này kế thừa các thuộc tính cũng như phương thức từ Prototype của mình. Bản thân Prototype là một instance object, chúng ta sử dụng thuộc tính __proto__ để truy cập tới nó.

Với mỗi function trong JavaScript sẽ có một thuộc tính prototype mặc định với kiểu dữ liệu là object. Để thực hiện kế thừa các thuộc tính và phương thức của 1 function trong JS, chúng ta sử dụng thuộc tính prototype này để thêm vào; sau đó thì các đối tượng con tạo ra bởi hàm khởi tạo (constructor) sẽ đều mang các giá trị trong thuộc tính prototype này. Điều này chính là điểm mấu chốt cho khái niệm Prototype chain hay là cơ chế triển khai kế thừa trong JavaScript.

Prototype là gì?

Ví dụ như hình vẽ trên, các object b và c sẽ đều có một Prototype là Foo.prototype có thể truy cập thông qua thuộc tính __proto__. Bản thân Foo là một function, nó sẽ chứa thuộc tính prototype; điều này có nghĩa rằng các object b, c được khởi tạo thông qua hàm constructor của Foo sẽ được kế thừa các phương thức như calculate hay thuộc tính x = 10 có sẵn. Đây chính là cơ chế triển khai tính kế thừa trong OOP của JavaScript.

  Prototype của object

  Prototype pattern – một trong những pattern phổ biến nhất

Prototype chain là gì?

Prototype chain hay chuỗi Prototype, như cái tên của nó, đề cập đến chuỗi quá trình lặp lại trong việc tìm ra các thuộc tính, phương thức đầy đủ của một đối tượng. Như đã nói ở phần trước, một object sẽ có một prototype của riêng mình chứa thông tin về các thuộc tính và phương thức. Vì thế khi ta gọi tới một thuộc tính (hay phương thức) của đối tượng, ban đầu JS sẽ tìm trong thuộc tính riêng của đối tượng; nếu không tìm thấy nó sẽ tiếp tục tìm trong prototype của đối tượng và lặp lại quá trình này với prototype của prototype của đối tượng cho đến khi gặp Object.prototype thì dừng lại và cho ra kết quả undefined nếu không tìm thấy.

Prototype chain là gì?

Tóm lại thì bạn cần nhớ rằng trong JS, mỗi đối tượng sẽ có một liên kết ẩn với prototype của nó – nơi mà sẽ khai báo các thuộc tính và phương thức mà đối tượng đó có, đồng thời cũng là một object chứa liên kết ẩn đến một prototype khác chứa thông tin về prototype này. Prototype chain chính là cơ chế cho phép các đối tượng truy cập vào toàn bộ các thuộc tính, phương thức được định nghĩa bên trong object và toàn bộ các chuỗi prototype gắn với nó.

Tham khảo việc làm Javascript lương hấp dẫn trên TopDev!

Cách sử dụng Prototype chain

Lý thuyết nhiều quá nên chúng ta sẽ đến với phần triển khai code để có thể dễ hiểu hơn nhé. Đầu tiên chúng ta khai báo 1 hàm Person như dưới đây với 2 thuộc tính có sẵn là nameemail:

function Person(name, email) {
  this.name = name;
  this.email = email;
}

Như đã nói ở phần trước thì function Person này sẽ có 1 thuộc tính là prototype; bản thân Prototype này cũng là một object, vì thế chúng ta có thể thêm thuộc tính số điện thoại vào cho nó:

Person.prototype.phone = "0987654321";

let nguyenVanA = new Person("Nguyễn Văn A", "a.nv@gmail.com");

console.log(nguyenVanA); // {name: 'Nguyễn Văn A', email: 'a.nv@gmail.com'}
console.log(nguyenVanA.phone); //0987654321

Đoạn code trên tạo ra đối tượng nguyenVanA với 2 thuộc tính (nameemail) có trong function Person và 1 thuộc tính (phone) lấy từ prototype của Student. Kết quả khi console.log ra nguyenVanA thì sẽ chỉ cho ra 2 thuộc tính nameemail; nhưng chúng ta vẫn sẽ truy cập được thuộc tính phone ở câu console.log bên dưới bình thường.

Tương tự với việc thêm phương thức (methods) cho prototype, chúng ta có thể triển khai như dưới đây:

Person.prototype.showName = function () {
  console.log(this.name);
};

console.log(nguyenVanA.showName()); //Nguyễn Văn A

Thuộc tính phone và phương thức showName được nằm trong chính prototype của Person.

Cách sử dụng Prototype chain

Để triển khai việc kế thừa code trong JavaScript, chúng ta có thể làm theo cách dưới đây. Trước tiên hãy tạo ra 1 hàm Student dùng cho việc kế thừa hàm Person ở trên (ở đây hiểu khái niệm hàm sẽ tương tự với khái niệm class trong OOP).

function Student(id, score) {
  this.id = id;
  this.score = score;

  this.showScore = function () {
    console.log(this.score);
  };
}

Student.prototype = new Person();

Student sẽ có thêm 2 thuộc tính là idscore cùng 1 phương thức là showScore. Ngoài ra prototype của Student được kế thừa từ Person nên chúng ta có thể dễ dàng sử dụng các thuộc tính name, email, phone hay phương thức showName.

let leThiB = new Student(1, 100);
leThiB.name = "Lê Thị B";
leThiB.showName(); //Lê Thị B
leThiB.showScore(); //100

console.log(leThiB.phone); //0987654321

Kết bài

Như vậy chúng ta đã cùng tìm hiểu về khái niệm Prototype chain trong JavaScript cùng với cách triển khai tính kế thừa trong ngôn ngữ lập trình này. Nắm chắc được cơ chế Prototype sẽ giúp bạn hiểu rõ hơn về JS cũng như OOP và cải thiện các kỹ năng lập trình của mình. Hy vọng bài viết hữu ích dành cho bạn và hẹn gặp lại trong các bài viết tiếp theo của mình.

Tác giả: Phạm Minh Khoa

Có thể bạn quan tâm:

Xem thêm các việc làm Developer hấp dẫn tại TopDev