Giới thiệu về OOP
Trong lập trình hướng đối tượng (OOP) có 4 tính chất là tính đóng gói (Encapsulation), tính kế thừa (Inheritance), tính đa hình (Polymorphism) và tính trừu tượng (Abstraction)

Mô hình OOP
1. Tính đóng gói
Trong Javascript, để thực hiện tính bao đóng, ta có thể tạo ra 1 Constructor Function, đóng gói toàn bộ các trường và hàm vào 1 object. Thông thường, các bạn hay khai báo như sau:
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.showName = function() {
console.log(this.firstName + ' ' + this.lastName);
};
}
var psn1 = new Person('Khoa', 'Nguyen');
// các property khai báo vào biến this có thể bị truy xuất từ bên ngoài
// object không còn bao đóng nữa
psn1.firstName = 'changed';
console.log(ps1.firstName); // changed
Với các khai báo này, tính bao đóng không được đảm bảo. Các property có thể bị truy cập, thay đổi từ bên ngoài. Ở đây, ta phải sử dụng biến cục bộ.
function Person(firstName, lastName) {
var fstName = firstName;
var lstName = lastName;
this.setFirstName = function(firstName) {
fstName = firstName;
};
this.getFirstName = function() {
return fstName;
};
this.setLastName = function(lastName) {
lstName = lastName;
};
this.getLastName = function() {
return lstName;
};
}
var person1 = new Person('Khoa', 'Nguyen');
console.log(person1.fstName); // Undefined, không thể truy cập được
console.log(person1.getFirstName()); // Khoa
Các biến cục bộ này chỉ có thể truy xuất trong Constructor Function, nó tương đương với các trường private trong Java.
Trong javascript, không có cách nào để tạo ra các trường protected (Chỉ có thể truy cập từ class kế thừa) như Java và C# được.
2. Tính kế thừa
Trong Javascript không có từ khóa extends cũng như class, vậy nên Prototype (and Prototype chains) là sự triển khai tính kế thừa đối tượng của Javascript.
Ví dụ:
function Person() {
this.firstName = 'Per';
this.lastName = 'son';
this.sayName = function() { return this.firstName + ' ' + this.lastName };
}
// Viết một Constructor Function khác
function SuperMan(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// Ta muốn SuperMan sẽ kế thừa các thuộc tính của Person
// Sử dụng prototype để kế thừa
SuperMan.prototype = new Person();
// Tạo một object mới bằng Constructor Function
var sm = new SuperMan('Khoa', 'Nguyen');
sm.sayName(); // Khoa Nguyen. Hàm này kế thừa từ prototype của Person
Khi trình thông dịch JS kiểm tra thuộc tính đối tượng định nghĩa cho nó, trước tiên nó kiểm kiểm tra object trước. Nếu object không có thuộc tính được định nghĩa, nó sẽ kiểm tra prototype của đối tượng với cùng thuộc tính, nếu nó được tìm thấy, nó sẽ trả về thuộc tính đó. Nó khác với OOP trong Java là prototype object có thể truy cập vào đối tượng tạo ra trước vào sau bất kể khi nào có sự thay đổi nào trên prototype
function Bread() {}; // constructor function
let brownBread = new Bread(); // object of type "Bread"
let sodaBread = new Bread(); // object of type "Bread"
Bread.prototype.toast = function() {
console.log('I am toasting!');
}; // set the function on a toast property on the prototype
// inherited prototype is accessible!
brownBread.toast(); // I am toasting!
sodaBread.toast(); // I am toasting!
3. Tính đa hình và trừu tượng
Đối với tính đa hình và tính trừu tượng, việc áp dụng 2 tính chất này trong Javascript là không rõ ràng. Do đó mình sẽ không trình bày trong bài viết này
Việc áp dụng lập trình hướng đối tượng vào JavaScript là tương đối khó. Tuy nhiên, nếu bạn nắm vững những kiến thức cơ bản mà mình đã trình bày trên đây, thì mình tin chắc rằng bạn sẽ dễ dàng tìm hiểu thêm và áp dụng lập trình hướng đối tượng trong JavaScript.




