Trong lập trình JavaScript, hai khái niệm hết sức quan trọng mà bất kỳ lập trình viên nào cũng cần nắm vững là prototype (nguyên mẫu) và inheritance (kế thừa). Để hiểu rõ hơn về cách thức hoạt động của chúng, chúng ta sẽ lần lượt tìm hiểu từng khái niệm và cách chúng tương tác với nhau.
Prototype
Prototype trong JavaScript đóng vai trò như một khuôn mẫu hoặc bản thiết kế cho các đối tượng được tạo ra từ một function constructor (hàm khởi tạo). Khi một object được tạo từ một function constructor, nó sẽ kế thừa các thuộc tính và phương thức được định nghĩa trong prototype của hàm khởi tạo đó.
Cú pháp để định nghĩa một prototype rất đơn giản:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log(`Hello, my name is ${this.name}`);
};
Trong ví dụ trên, greet
là một phương thức được định nghĩa trong prototype của Person
. Khi chúng ta tạo một đối tượng mới từ Person
, đối tượng này sẽ có quyền truy cập vào phương thức greet
thông qua prototype.
const john = new Person('John', 30);
john.greet(); // Output: Hello, my name is John
Kế thừa
Kế thừa là một khái niệm thiết yếu trong lập trình hướng đối tượng, cho phép một class (lớp) con thừa hưởng các tính năng từ một class cha. Trong JavaScript, kế thừa được thực hiện thông qua prototype.
Để thực hiện kế thừa trong JavaScript, chúng ta có thể sử dụng cú pháp Object.create()
hoặc ES6 class syntax. Các ví dụ sau đây sẽ minh họa cả hai cách.
Kế thừa bằng Object.create()
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a noise.`);
};
function Dog(name, breed) {
Animal.call(this, name); // Gọi hàm khởi tạo của Animal
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog; // Đặt lại constructor cho Dog
Dog.prototype.speak = function() {
console.log(`${this.name} barks.`);
};
const dog = new Dog('Rex', 'Labrador');
dog.speak(); // Output: Rex barks.
Trong ví dụ trên, Dog
kế thừa từ Animal
. Chúng ta sử dụng Object.create(Animal.prototype)
để tạo một object mới kế thừa từ prototype của Animal
. Sau đó, chúng ta đặt lại constructor
của Dog
để đảm bảo nó không tham chiếu đến Animal
.
Kế thừa bằng cú pháp ES6
JavaScript ES6 giới thiệu cú pháp class, giúp việc làm việc với kế thừa trở nên dễ hiểu và dễ đọc hơn.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // Gọi hàm khởi tạo của Animal
this.breed = breed;
}
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog('Rex', 'Labrador');
dog.speak(); // Output: Rex barks.
Ở đây, từ khóa extends
được sử dụng để thiết lập kế thừa. Từ khóa super
gọi hàm khởi tạo của class cha Animal
. Phương thức speak
được ghi đè trong class con Dog
.
Tóm tắt
Cả prototype và kế thừa là những khái niệm quan trọng trong JavaScript, giúp lập trình viên tái sử dụng mã nguồn và xây dựng các hệ thống phức tạp một cách dễ dàng. Việc nắm vững cách thức hoạt động của prototype và cách triển khai kế thừa không chỉ giúp bạn viết mã có cấu trúc hơn mà còn tăng cường khả năng tương tác giữa các thành phần trong ứng dụng của bạn.
Comments