Overview
TypeScript เติมเต็มสิ่งที่ JavaScript ขาดหายไปในโลก OOP นั่นคือ Encapsulation (การห่อหุ้มข้อมูล) และ Abstraction เราสามารถกำหนดสิทธิ์การเข้าถึงตัวแปรภายใน Class ได้จริง ไม่ใช่แค่ข้อตกลงด้วยปากเปล่าเหมือนใน JS (เช่น _variable)
Key Ideas
1. Access Modifiers
เครื่องมือคุมโซนของข้อมูล
public(Default): ใครก็เรียกใช้ได้private: ใช้ได้แค่ภายใน Class นี้เท่านั้น (ลูกก็ห้ามแตะ)protected: ใช้ได้ภายใน Class นี้ และ Class ลูก (Inheritance)
2. Constructor Shorthand
TypeScript ช่วยลดการเขียนโค้ดซ้ำซ้อนด้วยการประกาศ Access Modifier ใน Constructor ได้เลย
// เขียนย่อ (นิยมใช้)
constructor(public name: string, private age: number) {}
// มีค่าเท่ากับ
name: string;
private age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
3. Abstract Class
Class ต้นแบบที่ "ห้ามเอาไปสร้าง Object ตรงๆ" แต่มีไว้ให้ Class อื่นมาสืบทอดและ Implement ต่อให้เสร็จ
Example
abstract class Employee {
constructor(
public name: string,
protected salary: number,
) {}
// Method ทั่วไป
printInfo() {
console.log(`${this.name} earns ${this.getSalarySlip()}`);
}
// Abstract Method: ลูก "ต้อง" ไปเขียนเอง
abstract calculateBonus(): number;
// Helper method (protected)
protected getSalarySlip(): string {
return `$${this.salary}`;
}
}
class Developer extends Employee {
calculateBonus(): number {
return this.salary * 2; // เข้าถึง salary ได้เพราะเป็น protected
}
}
const dev = new Developer("Jane", 60000);
dev.printInfo();
// dev.salary; // ❌ Error: เข้าถึงจากข้างนอกไม่ได้ (protected)
Pitfalls (สิ่งที่ควรระวัง)
❌ 1. Private ใน TS ไม่ใช่ Private จริงใน Runtime
private ใน TypeScript มีผลแค่ตอน Compile (Static check) แต่เมื่อแปลงเป็น JavaScript แล้ว มันคือ Property ธรรมดาที่เข้าถึงได้ปกติ (ยกเว้นจะใช้ #privateField ของ JS ES2020 ซึ่งเป็น Private จริงๆ)
❌ 2. ใช้ Inheritance พร่ำเพรื่อ
Composition over Inheritance: ถ้าความสัมพันธ์ไม่ใช่ "is-a" (เป็นชนิดหนึ่งของ...) ให้ลองใช้การประกอบ Object แทนการสืบทอด
- ❌
User extends Database(ผิดหลัก) - ✅
User has a DatabaseConnection