Prototype là khái niệm cốt lõi đối với JavaScript, tuy nhiên đối với lập trình viên mới thì khái niệm này vẫn rất xa lạ. Những kiến thức này là những kiến thức cốt lõi trong lập trình. Vậy Prototype là gì và làm sao để thiết lập Prototype? Bài viết dưới đây sẽ giải đáp hết những thắc mắc cũng như những thông tin liên quan đến ngôn ngữ này. Theo dõi bài biết để hiểu rõ hơn về Prototype bạn nhé!

Prototype là gì?

Đây là cơ chế để thực hiện mô hình OOP của ngôn ngữ lập trình JavaScript, trong đó, các đối tượng kế thừa tính năng từ nhau. Mỗi một object trong Javascript đều có một thuộc tính nội bộ gọi là prototype.

Ngôn ngữ lập trình này được liên kết với mọi hàm và mọi object theo mặc định, trong đó thuộc tính prototype của hàm sẽ có thể truy cập cũng như sửa đổi. Còn thuộc tính prototype của object thì invisible.

Đó là loại object vô cùng đặc biệt có thể gắn các thuộc tính bổ sung vào, object này có thể sẽ được chia sẻ trên hầu hết các phiên bản của hàm khởi tạo.

Nói một cách dễ hiểu thì, prototype là một object trong JavaScript.

Prototype là gì?

Prototype của object

Thuộc tính Prototype của object là invisible. Để có thể truy cập Prototype object thì sử dụng phương thức Object.getPrototypeOf (obj) thay vì proto.

Prototype object gồm những thuộc tính và phương thức sau:

Thuộc tínhMô tả
ConstructorTrả về hàm đã tạo
__proto__Đây là thuộc tính của một object. Sẽ trả về prototype object một hàm mà được liên kết đến

Phương thức đối với Prototype Object

Phương thứcMô tả
HasOwnProperty()Trả về một boolean cho biết liệu rằng 1 object có thể chứa thuộc tính được chỉ định như một thuộc tính của object đó và không được kế thừa qua chuỗi các prototype hay không.
isPrototypeOf()Trả về một boolean cho biết liệu 1 object có được chỉ định có nằm trong chuỗi prototype của object mà phương thức này được gọi hay không
PropertyIsEnumerable()Trả về 1 boolean cho biết thuộc tính được chỉ định có thể liệt kê hay không
toLocaleString()Trả về trong string ở định dạng bố cục
toStringTrả về cho string
valueOfTrả về giá trị object được chỉ định

Prototype chain

Cơ chế của Prototype chain khá đơn giản: khi truy cập một thuộc tính trên object, JavaScript sẽ có thể tìm kiếm thuộc tính này bên trong đối tượng. Nếu engine không thể tìm kiếm được thì sẽ tiếp tục tìm kiếm trong nguyên mẫu của đối tượng cho đến khi đạt được đến Object.Prototype. Nếu cuộc tìm kiếm kết thúc và không có gì được tìm thấy kết quả sẽ không thể xác định. Ví dụ như:

var obj1 = {

  a: 1,

  b: 2

};

var obj2 = Object.create(obj1);

obj2.a = 2;

console.log(obj2.a); // 2

console.log(obj2.b); // 2

console.log(obj2.c); // undefined

Đoạn code này, câu lệnh var obj2 = object.create(obj1) sẽ tạo đối tượng obj2 với đối tượng Prototype obj1. Nói một cách khác thì obj1 sẽ trở thành prototype của obj2 thay vì Object. Như vậy, b không phải là thuộc tính của obj 2, vậy nên vẫn có thể truy cập thông qua prototype chain. Tuy nhiên, đối với thuộc tính c này thì sẽ có giá trị không thể xác định vì không thể tìm thấy trong Object.Prototype 1 và Obj1.

Cách thiết lập Prototype đúng cách

Có vô số cách khác nhau để thiết lập Prototype của một object trong JavaScript. Sẽ có 2 cách phổ biến nhất đó là: 

Dùng Object.create 

Phương thức này tạo ra một object mới cho phép bạn chỉ định một object được dùng để làm nguyên mẫu cho đối tượng mới.

Ví dụ như: 

const personPrototype = {

  greet() {

    console.log(‘hello!’);

  }

}

const carl = Object.create(personPrototype);

carl.greet();  // hello!

Khi tạo ra một object person Prototype, sẽ có phương thức great(). Sau đó sử dụng Object.create() để tạo nên một đối tượng mới với person Prototype làm prototype của nó. Và bây giờ có thể gọi great() trên đối tượng mới và prototype cung cấp việc triển khai của nó.

Dùng constructor

Đối với JavaScript, tất cả các hàm đều sẽ có những thuộc tính có tên là prototype. Khi gọi một hàm như một constructor thì thuộc tính này sẽ được đặt làm prototype của object mới. Vì thế, nếu đặt  prototype của một constructor thì chúng ta có thể đảm bảo rằng tất cả các object được tạo ra bằng constructor đều sẽ được cung cấp cho prototype đó. Ví dụ như:

const personPrototype = {

  greet() {

    console.log(`hello, my name is ${this.name}!`);

  }

}

function Person(name) {

  this.name = name;

}

Person.prototype = personPrototype;

Person.prototype.constructor = Person;

Tại đây chúng ta tạo ra:

  • Một object person Prototype với phương thức great()
  • Một hàm khởi tạo person(), giúp khởi tạo tên của người cần tạo.

Sau đó có thể đặt thuộc tính prototype của hàm Person trỏ về person Prototype.

Dòng cuối được đặt thuộc tính constructor của prototype cho hàm được dùng để tạo đối tượng Person. Đây là điều bắt buộc vì sau khi đặt Person.prototype=person Prototype. Thuộc tính này có thể trỏ về constructor cho personPrototype là Object chứ không phải là Person (vì personPrtotype được xây dựng như một object literal).

Sau code này thì các object được tạo bằng Person() sẽ lấy personPrototype của mình.

Constructor của prototype

Prototype, sự kế thừa

Đây là một tính năng vô cùng mạnh mẽ và rất linh hoạt của JavaScript, tính năng này sẽ giúp tái sử dụng code và kết hợp các object với nhau.

Đặc biệt là prototype còn hỗ trợ một số phiên bản kế thừa. Tính kế thừa là một trong những đặc điểm vô cùng nổi bật của Prototype.

Sự kế thừa là một tính năng của ngôn ngữ lập trình hướng đối tượng (OOP), cho phép người dùng lập trình chứng minh ý tưởng “ object trong hệ thống là phiên bản chuyên biệt của các object khác”

Ví dụ: Nếu bạn đang lập trình mô hình một trường học, trong trường học sẽ có họ sinh và các giáo sư, giảng viên hoặc các thầy cô giáo. Cả 2 đều là người, vì thế đều có những đặc điểm giống nhau như đều có tên. Tuy nhiên, mỗi người đều sẽ có thêm những đặc điểm bổ sung như giá sư, giảng viên hay các thầy cô giáo thì có thêm bộ môn họ dạy. Trong hệ thống lập trình hướng đối tượng, chúng ta có thể nói rằng tất cả họ đều sẽ có những thuộc tính kế thừa từ mọi người.

Trong JavaScript, nếu các đối tượng đó có thể có prototype người thì chúng đều sẽ có thể kế thừa các thuộc tính chung. Đồng thời, thêm và xác định lại những thuộc tính khác nữa.

Prototype, sự kế thừa

Cách sử dụng Prototype trong JavaScript

Ngôn ngữ này cho phép người dùng xác định một cách dễ dàng các phương thức cho tất cả các trường hợp của object. Cái hay ở đây đó là phương thức được áp dụng cho prototype vì thế chỉ được lưu trữ trong bộ nhớ một lần. Tuy nhiên, mọi instance của object đều sẽ có quyền truy cập vào.

Ví dụ như:

function Pet(name, species){

    this.name = name;

    this.species = species;

}

function view(){

    return this.name + ” is a ” + this.species + “!”;

}

Pet.prototype.view = view;

var pet1 = new Pet(‘Gabriella’, ‘Dog’);

alert(pet1.view()); //Outputs “Gabriella is a Dog!”

Trong hàm trên, chỉ với cách sử dụng prototype khi đính kèm phương thức xem, chúng ta mới có thể đảm bảo rằng tất cả các object pet đều có quyền truy cập và phương thức này để xem. Ngoài ra chúng ta còn có thể sử dụng phương pháp này để tạo ra vô số những hiệu ứng khác.

Ví dụ như: Chúng ta muốn có thêm một object Dog và object này kế thừa từng phương thức và từng thuộc tính được sử dụng trong object pet. Cùng với đó là thiết lập những tính năng đặc biệt chỉ có object Dog mới có quyền truy cập.

function Pet(name, species){

    this.name = name;

    this.species = species;

}

function view(){

    return this.name + ” is a ” + this.species + “!”;

}

Pet.prototype.view = view;

function Dog(name){

    Pet.call(this, name, “dog”);

}

Dog.prototype = new Pet();

Dog.prototype.bark = function(){

    alert(“Woof!”);

}

Trong hàm này, chúng ta đã thiết lập object Dog và gọi nó là hàm Pet với phương thức call(). Phương thức call cho phép bạn gọi hàm đích cụ thể bên trong của đối tượng bằng cách truyền vào đối tượng muốn chạy hàm theo sau là các đối số.

Sau đó sẽ cấp cho object Dog một phương thức là bark (chỉ có các object Dog mới có thể truy cập được)

var pet1 = new Pet(‘Trudy’, ‘Bird’);

var pet2 = new Dog(‘Gabriella’);

alert(pet2.view()); // Outputs “Gabriella is a Dog!”

pet2.bark(); // Outputs “Woof!”

pet1.bark(); // Error

Ngôn ngữ này được hoạt động theo một chuỗi. Khi gọi pet2.view(), trước tiên phải kiểm tra đối tượng Dog và Pet đã có phương thức xem nào chưa. Vì Dog là kế thừa của Pet và Pet là kế thừa của Object.prototype.

Object.prototype.whoAmI = function(){

    alert(“I am an object!”);

}

pet1.whoAmI(); //Outputs ‘I am an object!’

pet2.whoAmI(); //Outputs ‘I am an object!’

Cách sử dụng Prototype trong JavaScript

Như vậy chúng tôi đã chia sẻ đến bạn một số thông tin cơ bản về Prototype. Mong rằng bài viết sẽ giúp bạn hiểu hơn về Prototype là gì cũng như biết cách sử dụng Prototype trong JavaScript. Nếu bạn có bất kỳ những thắc mắc nào liên quan đến bài viết thì hãy liên hệ với chúng tôi để được giải đáp một cách nhanh chóng nhất nhé.

FPT Aptech trực thuộc Tổ chức Giáo dục FPT có hơn 25 năm kinh nghiệm đào tạo lập trình viên quốc tế tại Việt Nam, và luôn là sự lựa chọn ưu tiên của các sinh viên và nhà tuyển dụng.
0981578920
icons8-exercise-96