وراثة الفئات
ليس كل طلب مختلفًا من الصفر. ترث TeaOrder أساس الطلب من Order، ثم تضيف التفصيلة التي تخص الشاي.
من صفحة الكوكيز إلى الكائنات
انتهى المثال السابق بالسطر theme / dark. هنا لا نخزّن نصًا في المتصفح؛ بل ننشئ كائنات في الذاكرة.
ما يحتفظ به الأب
يأخذ Order الشراب والحجم، وتجمع label هاتين القيمتين في تسمية مشتركة.
class Order {
constructor(drink, size) {
this.drink = drink;
this.size = size;
}
label() {
return this.drink + " / " + this.size;
}
}
const order = new Order("tea", "regular");
console.log(order.label());
الناتج هو tea / regular. لذلك فـ order instanceof Order صحيحة، بينما تبقى الدالة مشتركة على prototype.
بداية الابن
تعلن extends Order أن الطلب الجديد ابنٌ للطلب العام. على الباني أن يهيئ الجزء الموروث أولًا.
class Order {
constructor(drink, size) {
this.drink = drink;
this.size = size;
}
label() {
return this.drink + " / " + this.size;
}
}
class TeaOrder extends Order {
constructor(drink, size, extra) {
super(drink, size);
this.extra = extra;
}
}
const tea = new TeaOrder("tea", "regular", "mint");
console.log(tea.drink);
console.log(tea.extra);
تظهر tea ثم mint. استعمال this.extra قبل super يؤدي إلى ReferenceError لأن this لم يصبح جاهزًا بعد.
عدّل من دون نسخ
يمكن للابن أن يكتب label الخاصة به، لكنه لا يحتاج إلى إعادة تركيب الشراب والحجم.
class Order {
constructor(drink, size) {
this.drink = drink;
this.size = size;
}
label() {
return this.drink + " / " + this.size;
}
}
class TeaOrder extends Order {
constructor(drink, size, extra) {
super(drink, size);
this.extra = extra;
}
label() {
return super.label() + " / " + this.extra;
}
}
console.log(new TeaOrder("tea", "regular", "mint").label());
النتيجة tea / regular / mint. وكائن الشاي ينجح مع instanceof Order ومع instanceof TeaOrder في الوقت نفسه.
توزيع المسؤولية
الأب يصف ما تحتاجه كل الطلبات، والابن يضيف ما لا يخص إلا طلبات الشاي. ليست الوراثة حلًا لمجرد تغيير اسم قيمة.
سطر الصفحة
تنشئ الصفحة طلب شاي ثم تعرض تسمية الابن بعد أن وسّع تسمية الأب.
<!DOCTYPE html>
<html>
<body>
<p id="line">…</p>
<script>
class Order {
constructor(drink, size) {
this.drink = drink;
this.size = size;
}
label() {
return this.drink + " / " + this.size;
}
}
class TeaOrder extends Order {
constructor(drink, size, extra) {
super(drink, size);
this.extra = extra;
}
label() {
return super.label() + " / " + this.extra;
}
}
document.querySelector("#line").textContent =
new TeaOrder("tea", "regular", "mint").label();
</script>
</body>
</html>
السطر الظاهر tea / regular / mint؛ أما theme / dark فهو أثر مثال الكوكيز السابق، وtea / regular هو سطر الأب فقط.
جرّب الترتيب
أنشئ Order، ثم TeaOrder مع mint. ضع super قبل this.extra، واستدعِ super.label() عندما تريد إضافة التفصيلة.
أخطاء تستحق الانتباه
لا تلمس this قبل super، ولا تكرر نص الأب كاملًا، ولا تنس أن كائن الابن ينتمي أيضًا إلى الأب.
الخلاصة
extends يصل الفئتين، وsuper(...) يجهز الجزء الموروث. إعادة التعريف مع super.label() تعطي السطر الكامل.
🧠 اختبر معرفتك
اختبر معرفتك
تحدى نفسك مع هذا الاختبار التفاعلي واكتشف مدى فهمك للموضوع
📝 التعليمات
- اقرأ كل سؤال بعناية
- اختر أفضل إجابة لكل سؤال
- يمكنك إعادة الاختبار عدة مرات كما تريد
- سيتم عرض تقدمك في الأعلى