JavaScript dựa trên nguyên mẫu (prototypes). Mỗi khi khai báo một đối tượng, thuộc tính prototype được tạo mở rộng các thuộc tính và phương thức liên kết với đối tượng đó.
Gần đây, nhiều nhà phát triển JavaScript tìm cách kết hợp thiết kế hướng đối tượng vào mã. Điều này dẫn đến loại đối tượng mới trong JavaScript gọi là class, mở rộng từ prototype.
Trong hướng dẫn này, chúng ta sẽ thảo luận class là gì, tại sao dùng chúng, và cách triển khai class trong mã. Chúng ta sẽ đi qua ví dụ để giúp bạn bắt đầu với class.
Class Trong JavaScript Là Gì?
Class là cách khai báo mẫu (template) cho một đối tượng.
Nếu bạn quen với ngôn ngữ lập trình hướng đối tượng, bạn sẽ biết chúng phụ thuộc nhiều vào class và đối tượng. Class giống như bản thiết kế cho loại dữ liệu: nó nói dữ liệu gì có thể lưu và phương thức nào có thể truy cập. Đối tượng là một thể hiện (instance) của class đó.
Ví dụ class là Book. Class này chứa bản thiết kế thông tin có thể lưu về sách và cách dữ liệu đó có thể thay đổi. Đối tượng có thể là A Streetcar Named Desire, là một cuốn sách riêng lẻ.
Trong JavaScript, class là những gì chúng ta gọi là syntactic sugar (cú pháp đường). Cú pháp class dễ dùng, nhưng không nhất thiết thêm chức năng mới.
Class thường dùng trong các framework JavaScript hiện đại như React và Next.js.
Class So Với Function
Nếu bạn nhớ một điều từ bài viết này, hãy nhớ: class chỉ là hàm bình thường.
Sự khác biệt duy nhất giữa class và biểu thức hàm là cách khai báo; hàm dùng từ khóa function và class dùng từ khóa class. Kỹ thuật, bạn có thể khai báo class mà không dùng từ khóa class.
Chúng ta có thể thấy chúng giống nhau bằng cách tạo hai hàm và in prototype:
const PlayerFunction = function() {}
const PlayerClass = class {}
console.log(Object.getPrototypeOf(PlayerFunction));
console.log(Object.getPrototypeOf(PlayerClass));
Biểu thức class và hàm trả về:
function ()
function ()
Cả hàm và class đều dùng cùng kiến trúc dựa trên prototype.
Cách Định Nghĩa Class
Làm thế nào để định nghĩa class? Đó là câu hỏi hay.
Bạn có thể định nghĩa class dùng từ khóa class. Khi đã định nghĩa class, có thể dùng hàm constructor() để khởi tạo nó với một số giá trị mặc định.
Mở console JavaScript và dán mã này:
class Book {
constructor(title, author) {
this.title = title;
this.author = author;
}
}
Điều này tạo class Book. Class có thể lưu hai giá trị, title và author, định nghĩa trong phương thức constructor. Để tạo đối tượng của class này, dùng mã:
var streetcar = new Book("A Streetcar Named Desire", "Tennessee Williams");
Chúng ta có thể truy xuất giá trị từ class như từ bất kỳ đối tượng nào:
console.log(streetcar.title);
Mã trả về: A Streetcar Named Desire.
Cách Định Nghĩa Phương Thức Class
Một lợi ích của dùng class so với prototype là bạn có thể khai báo phương thức bên trong class. Điều này nghĩa là không cần dùng cú pháp prototype để thêm phương thức mới vào hàm hiện có.
Xem ví dụ:
class Book {
constructor(title, author) {
this.title = title;
this.author = author;
}
getDetails() {
console.log(`${this.title} is a book written by ${this.author}.`);
}
}
Chúng ta khai báo phương thức getDetails() tồn tại bên trong class. Điều này hay vì giữ tất cả mã gom lại một chỗ. Hãy gọi hàm getDetails() :
var streetcar = new Book("A Streetcar Named Desire", "Tennessee Williams");
streetcar.getDetails();
Mã trả về:
A Streetcar Named Desire is a book written by Tennessee Williams.
Kế Thừa Class
Giống như mọi cấu trúc hướng đối tượng, class có thể kế thừa thuộc tính từ class khác.
Kế thừa là quá trình class con truy cập phương thức và dữ liệu từ class cha. Để kế thừa class, dùng từ khóa extends. Tạo file JavaScript hoặc mở console và dán mã:
class Fiction extends Book {
constructor(title, author, fiction) {
super(title, author);
this.fiction = true;
}
}
Chúng ta tạo class Fiction dùng class Book khai báo trước làm bản thiết kế. Trong mã, dùng từ khóa super() kế thừa giá trị title và author từ class cha, là Book. Sau đó, định nghĩa thuộc tính mới, fiction, giá trị mặc định true.
Hãy tạo đối tượng của class Fiction mới:
var gatsby = new Fiction("The Great Gatsby", "F. Scott Fitzgerald");
console.log(gatsby.fiction);
Mã trả về: true. Class Fiction lưu mục fiction mặc định true. Nếu thử truy cập giá trị này từ thể hiện của class Book, không trả về gì. Đó là vì "fiction" chỉ truy cập được trong class Fiction.
Getter Và Setter
Khi làm việc với class, bạn nên dùng hàm getter và setter.
Hàm getter cho phép truy xuất phương thức từ class. Hàm setter cho phép thay đổi giá trị mục cụ thể trong class. Các hàm này ký hiệu dùng từ khóa get và set tương ứng.
Xem mã sau:
class Book {
constructor(title, author) {
this.title = title;
this.author = author;
}
get author() {
return this.author;
}
set author(author) {
this.author = author;
}
}
Trong ví dụ, khai báo hai phương thức author. Một cho phép truy xuất giá trị author; đó là get. Phương thức kia cho phép thay đổi giá trị author.
Chúng ta thấy điều này hoạt động qua mã:
var streetcar = new Book("A Streetcar Named Desire", "");
streetcar.author = "Tennessee Williams";
console.log(streetcar.author);
Mã trả về: Tennessee Williams.
Chúng ta khởi tạo đối tượng streetcar với tiêu đề A Streetcar Named Desire. Sau đó đặt giá trị author thành Tennessee Williams dùng setter định nghĩa. Cuối cùng, in giá trị author ra bảng điều khiển dùng getter.
Kết Luận
Mặc dù class không thêm chức năng mới vào JavaScript, chúng làm cho việc viết hàm dễ hiểu hơn nếu bạn quen với lập trình hướng đối tượng.
Class trừu tượng hóa thiết kế dựa trên prototype của JavaScript và làm cho nó trông hướng đối tượng hơn. Từ "trông" (seem) quan trọng vì, nhớ lại, class là hàm. Class không hơn là syntactic sugar.
Bây giờ bạn đã sẵn sàng bắt đầu dùng class như chuyên gia JavaScript!