Trang chủ Javascript Lập trình hướng đối tượng

Lập trình hướng đối tượng

Nguyễn Dương 20-06-2024

- Lập trình hướng đối tượng là mô hình lập trình dựa trên khái niệm đối tượng. Mô hình lập trình sẽ quy định phong cách code, cách viết và tổ chức code.

- Sử dụng mô hình đối tượng để mô hình hóa, mô tả các khía cạnh trong thế giới thực

- Các object có thể chứa dữ liệu bao gồm thuộc tính (properties) và phương thức - method (code).

- Bằng cách sử dụng object chúng ta đóng gói tất cả dữ liệu và hành vi tương ứng thành một khối dễ dàng thao tác.

- Trong OOP, các đối tượng là các đoạn/khối mã độc lập; Các đối tượng là các khối xây dựng của ứng dụng và tương tác với nhau.

- Tương tác xảy ra thông qua giao diện công khai - public interface (API) -  các phương thức mà code bên ngoài đối tượng có thể truy cập và sử dụng để giao tiếp với đối tượng.

- OOP tồn tại để đáp ứng mục tiêu cấu trúc, tổ chức code linh hoạt hơn và dễ dàng bảo trì.

- Hiện nay OOP là mô hình lập trình được sử dụng rộng rãi nhất trong kỹ thuật lập trình.

 

Class (lớp) và instance trong OOP truyền thống

- Chúng ta đã sử dụng object trong những buổi học trước nhưng chúng ta mới có những object lỏng lẻo, chưa tương tác với nhau.

- Trong OOP chúng ta cần một cách thống nhất để tạo ra các object mới từ code của mình.

- Class như một bản thiết kế chi tiết, sau đó tạo ra object mới dựa trên các quy tắc được quy tắc trong class.

- Các object được tạo từ class được gọi là instance của class, instance là một đối tượng thực có các giá trị thuộc tính và hành vi thực.

 

4 nguyên lý cơ bản của OOP

- Trừu tượng: Sự trừu tượng cơ bản là bỏ đi hoặc ẩn chi tiết không quan trọng. Nó cho phép ta có cái nhìn tổng quan về những gì mà chúng ta triển khai.

- Đóng gói: Đóng gói là giữ một số thuộc tính và các phương thức private bên trong class để chúng không truy cập được từ bên ngoài class. Chúng ta luôn có mục tiêu là đóng gói hầu hết các trạng thái và phương thức và chỉ công khai các phương thức thiết yếu.

- Kế thừa: Trong OOP chúng ta có hai class có liên quan chặt chẽ với nhau, một class kế thừa class kia và chúng sẽ là class cha và class con. Class con kế thừa các thuộc tính và phương thức của class cha. Tính thừa kế làm cho tất cả các thuộc tính và phương thức của một class nhất định có sẵn cho class con, nó tạo thành một hệ thống phân cấp.

- Đa hình (nhiều hình dạng): Một class con có thể ghi đè một phương thức mà nó được thừa kế từ một class cha.

 

Prototype

Trong JS có một thứ gọi là Prototype, tất cả các đối tượng trong JS được liên kết với một đối tượng prototype nhất định.

Prototype là cơ chế quan trọng trong việc thực thi mô hình OOP trong JavaScript. Tất cả các object trong javascript đều có một thuộc tính là prototype, và các object này kế thừa các thuộc tính (properties) cũng như phương thức (methods) từ prototype của mình.

- Mỗi đối tượng có một prototype.

- Đối tượng prototype chứa các phương thức  và thuộc tính mà tất cả các đối tượng được liên kết với prototype đó có thể truy cập và sử dụng => Hành vi này gọi là kế thừa nguyên mẫu.

- Kế thừa nguyên mẫu là tất cả các đối tượng được liên kết với một đối tượng prototype nhất định, đối tượng có thể sử dụng các thuộc tính và phương thức của prototype đó.

- Kế thừa nguyên mẫu khác với kế thừa thông thường, đó là một instance kế thừa một class (có thể gọi là cơ chế ủy quyền).

Sử dụng thuộc tính prototype để khai báo phương thức thay cho phương pháp khai báo thẳng vào object

    class Person {
      constructor(firstName, lastName, age){
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
      }
    }

    Person.prototype.fullname = function() {
      return this.firstName + " " + this.lastName
    };

    const person1 = new Person("Nguyen", "Duong", 28);
    person1.nationality = "Vietnamese";
    console.log(`${person1.fullname()} - ${person1.age} - ${person1.nationality}` );

Trong ví dụ trên, bạn có thể thấy mình không hề khai báo hàm name trong class Person. Nhưng mình có thể thêm hàm đó ở ngoài class bằng prototype.


Thuộc tính đặc biệt __proto__

Nếu chúng ta tạo một object từ User, object mới tạo sẽ có một liên kết đến prototype của User. Các bạn có thể truy xuất bằng cách sử dụng __proto__. Thuộc tính này nằm trong Object.prototype, vì vậy khi một object dùng thuộc tính này, JavaScript sẽ tìm thấy thuộc tính __proto__ trong chuỗi nguyên mẫu (prototype chain)

let u = new User();

 

// sử dụng u.[[Prototype]] sẽ không thành công

 

console.log(u.__proto__ === User.prototype); // true

console.log(u.__proto__.__proto__ === Object.prototype); // true

console.log(User.prototype.__proto__ === Object.prototype); // true

 

Các bạn không nên sử dụng __proto__ (Object.prototype.__proto__) vì tính năng này có thể sẽ bị xóa khỏi một số trình duyệt. Thay vào đó chúng ta có thể sử dụng Object.getPrototypeOf().

const prototypeOf = Object.getPrototypeOf;
let u = new User();
// prototypeOf(u) === User.prototype;  // true
// prototypeOf(prototypeOf(u)) === Object.prototype // true

 Khác biệt giữa someobj.__proto__ với SomeFunction.prototype

__proto__ trỏ vào prototype object của someObj, còn prototype ở prototype object sẽ được gán làm prototype cho các object được tạo dựa trên SomeFunction

Lưu ý: khi khởi tạo class con kết thừa từ class cha, hàm super() cần được gọi trước khi bạn dùng nó trong class kế thừa (trong "sub-class")

Bài viết liên quan

Từ khóa this Từ khóa this
Scope và scope chain trong javascript Scope và scope chain trong javascript
Nguyên lý Javascript thực thi chương trình Nguyên lý Javascript thực thi chương trình
Bất đồng bộ trong javascript Bất đồng bộ trong javascript
Lập trình hướng đối tượng Lập trình hướng đối tượng
Event trong javascript Event trong javascript