Encapsulation (الكبسلة) هو مبدأ في OOP يعني إخفاء تفاصيل البيانات الداخلية للكائن (object) بحيث لا يمكن التلاعب بها مباشرة من خارج الكائن.
هذا يجعل الكائنات:
- أكثر أمانًا
- أسهل في التحكم
- مرنة للتطوير والصيانة
✅ في JavaScript، يتم تحقيق الـ Encapsulation بـ:
- الخصائص الخاصة (Private properties) باستخدام
#
- الدوال الخاصة (Private methods) أيضًا باستخدام
#
- استخدام Getters / Setters للتحكم في الوصول.
🧪 أولًا: الخصائص العامة (بدون Encapsulation)
class User {
constructor(name) {
this.name = name;
}
}
let user1 = new User("Ali");
console.log(user1.name); // Ali
user1.name = "Hacker 😈"; // يمكن تغييره مباشرة
console.log(user1.name); // Hacker 😈
JavaScript❌ غير آمن: أي شخص يمكنه تعديل البيانات من الخارج.
🟢 الآن: Encapsulation باستخدام الخصائص الخاصة #
class User {
#name; // خاصية خاصة
constructor(name) {
this.#name = name;
}
getName() {
return this.#name; // getter
}
setName(newName) {
if (newName.length > 2) {
this.#name = newName;
} else {
console.log("❌ الاسم قصير جدًا");
}
}
}
let user1 = new User("Ali");
console.log(user1.getName()); // ✅ Ali
user1.setName("Mo"); // ✅ تغيير مقبول
console.log(user1.getName()); // Mo
user1.setName("A"); // ❌ الاسم قصير جدًا
console.log(user1.#name); // ❌ Error: private field
JavaScript✅ فوائد Encapsulation:
الفائدة | الشرح |
---|---|
🛡️ الأمان | لا يمكن الوصول مباشرة إلى البيانات الحساسة |
📏 التحكم في التعديلات | باستخدام setters يمكنك فرض شروط |
🧼 سهولة التحديث والصيانة | يمكنك تغيير المنطق الداخلي دون تأثير خارجي |
🧪 التقليل من الأخطاء | لأن التعامل يتم فقط عبر واجهات محددة |
🛠️ استخدم get
و set
(الصيغة المختصرة):
class Product {
#price;
constructor(price) {
this.#price = price;
}
get price() {
return this.#price;
}
set price(value) {
if (value > 0) {
this.#price = value;
} else {
console.log("❌ السعر يجب أن يكون أكبر من صفر");
}
}
}
let p = new Product(100);
console.log(p.price); // 100
p.price = 200;
console.log(p.price); // 200
p.price = -50; // ❌ السعر يجب أن يكون أكبر من صفر
JavaScript🧠 ملاحظات مهمة:
- الخصائص الخاصة
#
لا يمكن الوصول لها من الخارج. get
وset
تجعل واجهة الكائن سهلة الاستخدام مثل الخصائص العادية.- هذه الميزات مدعومة في جميع المتصفحات الحديثة (ES2022+)
📦 مثال عملي واقعي (حساب بنكي):
class BankAccount {
#balance;
constructor(initialBalance) {
this.#balance = initialBalance;
}
deposit(amount) {
if (amount > 0) this.#balance += amount;
}
withdraw(amount) {
if (amount <= this.#balance) {
this.#balance -= amount;
} else {
console.log("❌ لا يوجد رصيد كافٍ");
}
}
get balance() {
return this.#balance;
}
}
let acc = new BankAccount(1000);
acc.deposit(500);
acc.withdraw(300);
console.log(acc.balance); // 1200
acc.withdraw(2000); // ❌ لا يوجد رصيد كافٍ
JavaScript💬 مثال خاطئ بدون encapsulation:
class BankBad {
constructor(balance) {
this.balance = balance;
}
}
let bad = new BankBad(1000);
bad.balance = -999999; // ❌ تلاعب مباشر!
JavaScript→ هذا مثال على كود ضعيف الأمان.
✅ خلاصة:
المفهوم | التفاصيل |
---|---|
Encapsulation | إخفاء البيانات داخل الكلاس |
الخصائص الخاصة | باستخدام #name |
الوصول الآمن | عبر get و set |
فائدته | حماية البيانات وتنظيم الكود |