Lớp trong JavaScript

Lớp trong JavaScript

Bài viết này giải thích về lớp trong JavaScript.

YouTube Video

Lớp trong JavaScript

Trong JavaScript, một lớp kết hợp khái niệm lập trình hướng đối tượng và đóng vai trò như một bản thiết kế cho các đối tượng. Với lớp, bạn có thể định nghĩa ngắn gọn các thuộc tínhphương thức của đối tượng, cải thiện tính tái sử dụng và tổ chức mã. Cú pháp lớp đã được giới thiệu trong JavaScript với ES6.

Định nghĩa Lớp

Một lớp được định nghĩa với từ khóa class và thường được khởi tạo bằng một phương thức gọi là constructor.

 1class Person {
 2    // Constructor method (called when the class is instantiated)
 3    constructor(name, age) {
 4        this.name = name; // Property definition
 5        this.age = age;
 6    }
 7
 8    // Method definition
 9    greet() {
10        return `Hello, my name is ${this.name}`;
11    }
12}
13
14// Instantiation of the class
15const alice = new Person("Alice", 25);
16console.log(alice.greet()); // Hello, my name is Alice
  • Chúng ta định nghĩa một lớp bằng class Person.
  • constructor là một phương thức đặc biệt được tự động gọi khi một đối tượng được tạo.
  • Từ khóa this tham chiếu đến thực thể (đối tượng) của lớp trong lớp.

Thuộc tính và Phương thức của Lớp

Một lớp có thể định nghĩa thuộc tínhphương thức. Thuộc tính đại diện cho các đặc điểm của một đối tượng, và phương thức đại diện cho các chức năng của nó.

 1class Car {
 2    constructor(brand, model) {
 3        this.brand = brand;
 4        this.model = model;
 5    }
 6
 7    // Method definition
 8    drive() {
 9        console.log(`Driving a ${this.brand} ${this.model}`);
10    }
11}
12
13const car1 = new Car("Toyota", "Corolla");
14car1.drive(); // Driving a Toyota Corolla

Trong ví dụ này, một lớp Car được khai báo với các thuộc tính brandmodel và một phương thức drive.

Kế thừa Lớp

Các lớp có thể kế thừa từ các lớp khác. Bằng cách sử dụng kế thừa, bạn có thể tạo một lớp mới dựa trên một lớp hiện có và thêm các chức năng bổ sung cho nó.

 1class Animal {
 2    constructor(name) {
 3        this.name = name;
 4    }
 5
 6    speak() {
 7        console.log(`${this.name} makes a noise`);
 8    }
 9}
10
11// Inherit from the Animal class
12class Dog extends Animal {
13    constructor(name, breed) {
14        super(name); // Call the constructor of the parent class (Animal)
15        this.breed = breed;
16    }
17
18    // Override the method
19    speak() {
20        console.log(`${this.name} barks`);
21    }
22}
23
24const dog = new Dog("Rex", "German Shepherd");
25dog.speak(); // Rex barks

Trong ví dụ này, lớp Dog kế thừa từ lớp Animal.

  • Từ khóa extends được sử dụng để kế thừa từ lớp Animal.
  • Trong constructor của lớp Dog, super() được sử dụng để gọi constructor của lớp cha. Điều này cho phép bạn kế thừa quá trình khởi tạo của lớp cha.
  • Trong lớp được kế thừa, bạn có thể ghi đè các phương thức của lớp cha. Trong ví dụ này, thay vì "Rex tạo ra một âm thanh", "Rex sủa" được hiển thị.

Phương thức Tĩnh

Khi bạn định nghĩa một phương thức tĩnh trong một lớp, phương thức này sẽ được liên kết với chính lớp đó. Phương thức tĩnh có thể được gọi mà không cần khởi tạo đối tượng.

1class MathUtils {
2    // Static method
3    static add(a, b) {
4        return a + b;
5    }
6}
7
8console.log(MathUtils.add(5, 10)); // 15

Trong ví dụ này, lớp MathUtils có một phương thức tĩnh tên là add được định nghĩa.

  • Từ khóa static được sử dụng để định nghĩa một phương thức tĩnh.
  • Phương thức tĩnh không thuộc về các instance của lớp và có thể được gọi trực tiếp từ chính lớp đó.

Getters và Setters

Bằng cách định nghĩa getterssetters trong một lớp, bạn có thể đóng gói việc truy cập và thiết lập các thuộc tính.

 1class Rectangle {
 2    constructor(width, height) {
 3        this.width = width;
 4        this.height = height;
 5    }
 6
 7    // Getter
 8    get area() {
 9        return this.width * this.height;
10    }
11
12    // Setter
13    set widthValue(newWidth) {
14        this.width = newWidth;
15    }
16}
17
18const rect = new Rectangle(10, 20);
19console.log(rect.area); // 200
20
21rect.widthValue = 15;
22console.log(rect.area); // 300

Trong ví dụ này, lớp Rectangle định nghĩa một getter area và một setter widthValue.

  • Getter (get) được gọi khi truy cập giá trị của một thuộc tính.
  • Setter (set) được gọi khi thiết lập giá trị của một thuộc tính.

Cú pháp Đường tắt của Lớp

Trong JavaScript, cú pháp lớp được triển khai nội bộ bằng cách sử dụng hàm khởi tạo (constructor)prototype. Cú pháp lớp là cú pháp đường tắt giúp viết chúng ngắn gọn hơn.

 1// Example without using class syntax
 2function Person(name, age) {
 3    this.name = name;
 4    this.age = age;
 5}
 6
 7Person.prototype.greet = function() {
 8    return `Hello, my name is ${this.name}`;
 9};
10
11const person = new Person("Alice", 25);
12console.log(person.greet()); // Hello, my name is Alice

Trong ví dụ này, một hàm khởi tạo Person được định nghĩa và phương thức greet được định nghĩa bằng cách sử dụng prototype.

Xử lý this

Từ khóa this trong một lớp tham chiếu đến instance của lớp đó. Tuy nhiên, khi làm việc với this trong các phương thức của lớp, bạn cần chú ý rằng hành vi của nó có thể thay đổi tùy thuộc vào phạm vi. Vấn đề có thể xảy ra đặc biệt khi sử dụng các phương thức như là các hàm callback.

 1class Counter {
 2    constructor() {
 3        this.count = 0;
 4    }
 5
 6    increment() {
 7        this.count++;
 8        console.log(this.count);
 9    }
10}
11
12const counter = new Counter();
13setTimeout(counter.increment, 1000); // NaN
14// NaN, since this.count is undefined, it becomes NaN after incrementing.

Trong trường hợp như vậy, khi được truyền dưới dạng callback cho setTimeout, tham chiếu của this mà nó chỉ tới có thể thay đổi. Để tránh vấn đề này, nên cố định this bằng cách sử dụng phương thức bind hoặc sử dụng hàm mũi tên.

 1class Counter {
 2    constructor() {
 3        this.count = 0;
 4    }
 5
 6    increment() {
 7        this.count++;
 8        console.log(this.count);
 9    }
10}
11
12const counter = new Counter();
13
14// When using bind
15setTimeout(counter.increment.bind(counter), 1000);
16
17// When using an arrow function
18setTimeout(() => counter.increment(), 2000);

Tóm tắt

  • Lớp được sử dụng như là bản thiết kế để tạo đối tượng, định nghĩa các thuộc tính và phương thức.
  • Bạn có thể sử dụng kế thừa để mở rộng một lớp, tận dụng các khái niệm hướng đối tượng.
  • Phương thức tĩnh thuộc về chính lớp đó và có thể được sử dụng mà không cần tạo instance.
  • Bạn có thể đóng gói các thuộc tính bằng cách sử dụng getterssetters.
  • Cú pháp lớp (class) của JavaScript là syntax sugar và nội bộ sử dụng kế thừa dựa trên prototype.

Bằng cách sử dụng các lớp (class), bạn có thể xử lý lập trình hướng đối tượng một cách tự nhiên hơn và cải thiện khả năng tái sử dụng cũng như bảo trì mã.

Bạn có thể làm theo bài viết trên bằng cách sử dụng Visual Studio Code trên kênh YouTube của chúng tôi. Vui lòng ghé thăm kênh YouTube.

YouTube Video