مفهوم ميراث JS
طريقتان من الميراث التاليتين تستخدم عادة في JS:
ميراث سلسلة النموذج الأولي (الميراث بين الأشياء)
الميراث الكلاسيكي (الميراث بين البنائين)
نظرًا لأن JS ليست لغة موجهة نحو الكائنات مثل Java ، فإن JS تعتمد على الكائن وليس لديها مفهوم للفئات. لذلك ، إذا كنت ترغب في تنفيذ الميراث ، فيمكنك استخدام آلية النموذج الأولي لـ JS أو استخدام طرق التطبيق والاتصال لتنفيذها
في لغة موجهة نحو الكائن ، نستخدم الفئات لإنشاء كائن مخصص. ومع ذلك ، كل شيء في JS هو كائن ، لذلك ما هي الطريقة التي يمكن استخدامها لإنشاء كائن مخصص؟ هذا يتطلب النموذج الأولي JS:
يمكننا ببساطة اعتبار النموذج الأولي كقالب. الكائنات المخصصة التي تم إنشاؤها حديثًا هي نسخة من هذا القالب (النموذج الأولي) (في الواقع ليس نسخة ولكن رابط ، ولكن هذا النوع من الارتباط غير مرئي. هناك مؤشر __proto__ غير مرئي داخل الكائن الذي تم إنشاءه حديثًا ، مشيرًا إلى كائن النموذج الأولي).
يمكن لـ JS محاكاة وتنفيذ وظائف الفئات من خلال المُنشئين والنماذج الأولية. بالإضافة إلى ذلك ، يتحقق تنفيذ ميراث نوع JS أيضًا من خلال الاعتماد على سلاسل النموذج الأولي.
النموذج الأولي الميراث والميراث الطبقي
الميراث الكلاسيكي هو نداء مُنشئ SuperType داخل مُنشئ النوع الفرعي.
الميراث الطبقي الصارم ليس شائعًا جدًا ، ويستخدم بشكل عام في تركيبة:
نسخة الكود كما يلي:
وظيفة Super () {
this.colors = ["Red" ، "Blue"] ؛
}
وظيفة sub () {
Super.Call (هذا) ؛
}
تتمثل ميراث النموذج الأولي في إنشاء كائن جديد بمساعدة الكائنات الموجودة وتوجيه النموذج الأولي للفئة الفرعية إلى الفئة الأصل ، وهو ما يعادل إضافة سلسلة النموذج الأولي للفئة الأصل.
ميراث سلسلة النموذج الأولي
من أجل أن ترث فئة الطفل خصائص فئة الأصل (بما في ذلك الأساليب) ، من الضروري تحديد مُنشئ أولاً. بعد ذلك ، قم بتعيين مثيل جديد للفئة الأصل إلى النموذج الأولي للمُنشئ. الرمز كما يلي:
نسخة الكود كما يلي:
<script>
وظيفة Parent () {
this.name = 'mike' ؛
}
وظيفة الطفل () {
this.age = 12 ؛
}
child.prototype = New Parent () ؛ // يرث الطفل الوالد ويشكل سلسلة من خلال النموذج الأولي.
var test = New Child () ؛
تنبيه (اختبار.) ؛
التنبيه (test.name) ؛ // الحصول على سمات موروثة
// تواصل وراثة سلسلة النموذج الأولي
وظيفة Brother () {// Brother Construct
this.weight = 60 ؛
}
Brother.Prototype = New Child () ؛ // تابع الوراثة سلسلة النموذج الأولي
var brother = New Brother () ؛
في حالة تأهب (brother.name) ؛ // وراثة الوالدين والطفل ، يظهر مايك
تنبيه (brother.age) ؛ // pop 12
</script>
لا يزال وراثة سلسلة النموذج الأولي أعلاه مفقودة رابط واحد ، وهو كائن ، وجميع المنشئين موروثة من الكائن. يتم إكمال كائن الوراثة تلقائيًا ولا يتطلب الميراث اليدوي من قبل أنفسنا. إذن ما هي علاقتهم المرؤوس؟
تحديد العلاقة بين النموذج الأولي والمثال
هناك طريقتان لتحديد العلاقة بين النموذج الأولي والمثيل. extomeof Operator و ISProtypeOF () طرق:
نسخة الكود كما يلي:
تنبيه (كائن مثيل شقيق) // صحيح
التنبيه (اختبار مثيل من الأخ) ؛ // خطأ ، الاختبار هو الفئة الفائقة للأخ
تنبيه (مثال شقيق الطفل) ؛ // صحيح
تنبيه (مثيل شقيق الوالد) ؛ // صحيح
طالما أنه نموذج أولي يظهر في سلسلة النموذج الأولي ، يمكن القول أنه النموذج الأولي للمثال المشتق من سلسلة النموذج الأولي. لذلك ، ستعود طريقة isPrototypeoF () أيضًا.
في JS ، تسمى الوظيفة الموروثة supertype (فئة الأصل ، فئة أساسية ، وكذلك) وتسمى الوظيفة الموروثة نوعًا فرعيًا (فئة فرعية ، فئة مشتقة). استخدام ميراث النموذج الأولي ينطوي بشكل أساسي على قضيتين:
أولاً ، ستعمل إعادة كتابة النماذج الأولية على كسر العلاقة ، واستخدام النموذج الأولي لنوع المرجع ، ولا يمكن للنوع الفرعي نقل المعلمات إلى supertype.
يحل الفئة الزائفة مشكلة المشاركة المرجعية و SuperTypes غير قادرة على تمرير الحجج. يمكننا استخدام تقنية "Borrow Constructor".
مُنشئ الاقتراض (الميراث الكلاسيكي)
نسخة الكود كما يلي:
<script>
وظيفة الوالد (العمر) {
this.name = ['Mike' ، 'Jack' ، 'Smith'] ؛
this.age = العمر ؛
}
وظيفة الطفل (العمر) {
Parent.Call (هذا ، العمر) ؛
}
اختبار var = طفل جديد (21) ؛
تنبيه (test.age) ؛ // 21
ALERT (test.name) ؛ // Mike ، Jack ، Smith
test.name.push ('bill') ؛
ALERT (test.name) ؛ // Mike ، Jack ، Smith ، Bill
</script>
على الرغم من أن مصممي الاقتراض قاموا بحل المشكلتين الآن ، بدون نماذج أولية ، لا توجد طريقة لإعادة استخدامها ، لذلك نحتاج إلى نمط مُنشئ للاقتراض من سلسلة النموذج الأولي +. ويسمى هذا النمط الوراثة الجمع.
الجمع بين الميراث
نسخة الكود كما يلي:
<script>
وظيفة الوالد (العمر) {
this.name = ['Mike' ، 'Jack' ، 'Smith'] ؛
this.age = العمر ؛
}
parent.prototype.run = function () {
إرجاع this.name + 'كلاهما " + this.age ؛
} ؛
وظيفة الطفل (العمر) {
Parent.Call (هذا ، العمر) ؛ // الكائن ينتحل شخصية ويمرر المعلمات إلى الأنواع الفائقة
}
child.prototype = new Parent () ؛ // النموذج الأولي ميراث
اختبار var = طفل جديد (21) ؛ // كتابة الوالد الجديد (21) على ما يرام
ALERT (TEST.RUN ()) ؛ // Mike ، Jack ، Smith Hread21
</script>
الميراث الجمع هو طريقة الميراث شائع الاستخدام نسبيا. الفكرة وراء ذلك هي استخدام سلسلة النموذج الأولي لتنفيذ ميراث خصائص وأساليب النموذج الأولي ، وتنفيذ ميراث خصائص المثيل عن طريق الاقتراض. وبهذه الطريقة ، يتم تحقيق تعدد الوظائف من خلال تحديد الأساليب على النموذج الأولي ، وضمان أن كل مثيل له خصائصه الخاصة.
استخدام Call (): استدعاء طريقة كائن ما واستبدل الكائن الحالي بكائن آخر.
نسخة الكود كما يلي:
call ([thisobj [، arg1 [، arg2 [، [، .argn]]]]])))
النموذج الأولي الميراث
تسمى طريقة وراثة إنشاء كائنات جديدة استنادًا إلى الكائنات الموجودة دون إنشاء أنواع مخصصة وراثة النموذج الأولي
نسخة الكود كما يلي:
<script>
وظيفة OBJ (O) {
الدالة f () {}
f.prototype = o ؛
إرجاع جديد f () ؛
}
var box = {
الاسم: 'Trigkit4' ،
ARR: ["الأخ" ، "الأخت" ، "بابا"]
} ؛
var b1 = obj (box) ؛
تنبيه (b1.name) ؛ // trigkit4
b1.name = 'mike' ؛
تنبيه (b1.name) ؛ // مايك
تنبيه (B1.arr) ؛ // الأخ ، أخت ، بابا
b1.arr.push ('الآباء') ؛
تنبيه (b1.arr) ؛ // الأخ ، أخت ، بابا ، والآباء
var b2 = obj (box) ؛
تنبيه (b2.name) ؛ // trigkit4
تنبيه (b2.arr) ؛ // الأخ ، أخت ، بابا ، أولياء الأمور
</script>
ينشئ ميراث النموذج الأولي أولاً مُنشئًا مؤقتًا داخل وظيفة OBJ () ، ثم يستخدم الكائن الذي تم تمريره كنموذج أولي للمقدم ، ويعيد أخيرًا مثيلًا جديدًا من هذا النوع المؤقت.
الميراث الطفيلي
تجمع طريقة الميراث هذه بين نموذج النموذج الأولي + المصنع ، وغرض عملية إنشاء التغليف.
نسخة الكود كما يلي:
<script>
وظيفة إنشاء (س) {
var f = obj (o) ؛
f.run = function () {
إرجاع this.arr ؛ // بالمثل ، سيتم مشاركة المراجع
} ؛
العودة و ؛
}
</script>
مشاكل صغيرة مع الجمع بين الميراث
الميراث الجمع هو وضع الميراث الأكثر استخدامًا في JS ، ولكن سيتم استدعاء النمط الخارق للميراث المشترك مرتين أثناء الاستخدام ؛ مرة واحدة عند إنشاء نوع فرعي ، والآخر داخل مُنشئ النوع الفرعي.
نسخة الكود كما يلي:
<script>
وظيفة الوالد (الاسم) {
this.name = name ؛
this.arr = ['brother' ، 'Sister' ، 'Parents'] ؛
}
parent.prototype.run = function () {
إرجاع هذا.
} ؛
وظيفة الطفل (الاسم ، العمر) {
Parent.Call (هذا ، العمر) ؛ // المكالمة الثانية
this.age = العمر ؛
}
child.prototype = New Parent () ؛ // المكالمة الأولى
</script>
الرمز أعلاه هو الميراث المركب السابق ، لذا فإن الميراث المركب الطفيلي يحل مشكلة مكالمتين.
الجمع الطفيلي الميراث
نسخة الكود كما يلي:
<script>
وظيفة OBJ (O) {
الدالة f () {}
f.prototype = o ؛
إرجاع جديد f () ؛
}
وظيفة إنشاء (الوالد ، اختبار) {
var f = obj (parent.prototype) ؛ // إنشاء كائن
f.constructor = اختبار ؛ // كائن محسّن
}
وظيفة الوالد (الاسم) {
this.name = name ؛
this.arr = ['brother' ، 'Sister' ، 'Parents'] ؛
}
parent.prototype.run = function () {
إرجاع هذا.
} ؛
وظيفة الطفل (الاسم ، العمر) {
parent.call (هذا ، الاسم) ؛
this.age = العمر ؛
}
النمط الوراثي (الوالد ، الطفل) ؛ // يتحقق الوراثة من خلال هنا
var test = New Child ('TrigKit4' ، 21) ؛
test.arr.push ('ابن أخت') ؛
التنبيه (test.arr) ؛ //
التنبيه (test.run ()) ؛ // فقط يتم مشاركة الطريقة
var test2 = طفل جديد ('جاك' ، 22) ؛
التنبيه (Test2.arr) ؛ // حل مشكلة الاقتباس
</script>
الاتصال والتطبيق
تطبق الوظائف العالمية ويمكن استخدام المكالمة لتغيير الإشارة إلى هذا في الوظيفة ، على النحو التالي:
نسخة الكود كما يلي:
// تحديد وظيفة عالمية
وظيفة foo () {
console.log (this.fruit) ؛
}
// تحديد متغير عالمي
var fruit = "Apple" ؛
// تخصيص كائن
حزمة var = {
الفاكهة: "برتقالي"
} ؛
// ما يعادل window.foo () ؛
foo.apply (نافذة) ؛ // "Apple" ، هذا يساوي النافذة
// هذا === حزمة في فو
foo.apply (حزمة) ؛ // "البرتقالي"