إذا كنت لا تستطيع حقًا فهم بعض المعرفة في ذلك الوقت ، فيمكنك تركها في الوقت الحالي وتركها في المستقبل وربما يمكنك فهمها.
قبل بضعة أشهر ، كنت أحمل "JavaScript Advanced Programming (الإصدار الثالث)" وبعد مضغه على إنشاء الكائن ، بدأت في مضغ الميراث. ومع ذلك ، بعد مضغ سلسلة النموذج الأولي ، لم أعد أستطيع الوقوف بعد الآن ، وأصبح عقلي أكثر فوضى ، لذلك رميته جانباً واستمرت في النظر إلى هذا الأخير. الآن بعد أن استخدمت هذه العطلة الصيفية لفهم هذا الميراث ، سأقوم بفرز ملاحظاتي.
النموذج الأولي
دعنا نقرأ مقالًا أولاً. مؤلف المقال جيد جدًا ومجهز بصور عالية الدقة. مضحك جداً…
الرابط: [ملاحظات الدراسة] عرض سلسلة النموذج الأولي JS من منظور صغير
بضع كلمات من النص الأصلي
تحديد العلاقة بين النموذج الأولي والمثال
هناك طريقتان لاكتشاف العلاقة بين النموذج الأولي ومثال:
مثيل: يحدد ما إذا كان الكائن مثيلًا لكائن آخر
آلية الحوسبة الداخلية لمثلة OF هي كما يلي:
FunctionInstance_of (l ، r) {// l يمثل التعبير الأيسر ، r يمثل التعبير الصحيح varo = r.prototype ؛ // خذ النموذج الأولي لـ r l = l .__ proto__ ؛ // خذ النموذج الأولي الضمني لـ l بينما (صحيح) {if (l === null) returnfalse ؛ if (o === l) // هنا النقطة: عندما تكون O مساوية تمامًا لـ l ، return truereturntrue ؛ l = l .__ proto__ ؛ }}الكود أعلاه مقتطف من: تحليل متعمق لمشغل JavaScript Operator
isprototypeof (): يختبر ما إذا كان هناك كائن على سلسلة النموذج الأولي لكائن آخر
يرجى الرجوع إلى الاختلافات بين هاتين الطريقتين: javaScript isPrototypeof vs extryof use
استخدم سلسلة النموذج الأولي فقط لتحقيق الميراث
العيوب: 1. ستم مشاركة سمات النموذج الأولي الذي يشير إلى قيمة النوع بواسطة المثيل ؛ 2. عند إنشاء مثيل من النوع الفرعي ، لا يمكن تمرير المعلمات إلى مُنشئ SuperType.
functionFather () {this.name = "الأب" ؛ this.friends = ['aaa' ، 'bbb'] ؛ الأب console.log (s2.name) ؛ // phathers1.name = "son" ؛ console.log (s1.name) ؛ // sonconsole.log (s2.name) ؛ // doadconsole.log (s1.friends) ؛ // ["aaa" ، "bbb"] console.log (s2.friends) ؛ "bbb"] s1.friends.push ('ccc' ، 'ddd') ؛ console.log (s1.friends) ؛ // ["aaa" ، "bbb" ، "ccc" ، "ddd"]]فقط استخدم المُنشئين لتحقيق الميراث
طريقة التنفيذ: اتصل بمنشئ SuperType داخل مُنشئ النوع الفرعي (باستخدام طرق تطبيق () و Call ())
المزايا: حل مشكلة مرجع سمات نوع في النموذج الأولي ، ويمكن للمسارات الفرعية نقل المعلمات إلى فئات فائقة
العيوب: لا يمكن لحالات الفئة الفرعية الوصول إلى الأساليب المحددة في النموذج الأولي للصف الأصل (الفئة الفائقة) ، لذلك لا توجد طريقة للحديث عن إعادة استخدام الوظيفة.
functionFather (name ، friends) {this.name = name ؛ this.friends = friends ؛} الأب. النموذجي. الأب. call (هذا ، الاسم ، ['aaa' ، 'bbb']) ؛ هذا. Son2s1.friends.push ('ccc' ، 'ddd') ؛ console.log (s1.friends) ؛ // ["aaa" ، "bbb" ، "ccc" ، "ddd"] console.log (s2.flists) ؛ // ["AAA" ، "BBB" // subclass yeval () // typeerror: s1.getName ليس وظائف 2.GetName () ؛ // typeerror: S2.GetName ليس وظيفةالجمع بين الميراث
طريقة التنفيذ: استخدم سلسلة النموذج الأولي لتنفيذ ميراث خصائص وطرق النموذج الأولي ، واستخدم المنشئ لتنفيذ ميراث خصائص المثيل.
functionFather (name ، friends) {this.name = name ؛ this.friends = friends ؛} الأب. الأب. call (هذا ، الاسم ، ['aaa' ، 'bbb']) ؛ هذا. = Newson ('son1' ، 12) ؛ s1.friends.push ('ccc') ؛ console.log (s1.friends) ؛ // ["aaa" ، "bbb" ، "ccc"] console.log (s1.money) ؛ // 100k $ s1.getname () ؛ // son1s1.getage () ؛ // 12vars2 = newson ('son2' ، 24) ؛ console.log (s2.friends) ؛ // ["aaa" ، "bbb"] console.log (s2.money) ؛ // 100k $ s2.getName () ؛ // son2s2.getage () ؛ // 24يتجنب الوراثة المركب عيب من جانب واحد باستخدام سلاسل أو منشئات النموذج الأولي لتنفيذ الميراث ، ويجمع بين مزاياها ، ويصبح نموذج الميراث الأكثر شيوعًا في JavaScript ، ولكنه معيب أيضًا ، وسيتم ذكر عيب المركب على وجه التحديد لاحقًا.
الميراث النموذجي
فكرة التنفيذ: استخدم النماذج الأولية لإنشاء كائنات جديدة بناءً على الكائنات الموجودة ، دون إنشاء أنواع مخصصة بسبب هذا.
لتحقيق ذلك ، يتم تقديم الوظيفة التالية (OBJ)
functionObj (o) {functionf () {} f.prototype = o ؛ returnnewf () ؛} varperson1 = {name: "percy" ، الأصدقاء: ['aaa' ، 'bbb']} ؛ varperson2 = obj (person1) ؛ person.name = "zyj" ؛ percyconsole.log (person2.name) ؛ // zyjconsole.log (person1.friends) ؛ // ["aaa" ، "bbb" ، "ccc"] console.log (person2 في حالة المرور في معلمة ، تتصرف أساليب الكائن. varperson1 = {name: "percy" ، الأصدقاء: ['aaa' ، 'bbb']} ؛ varperson2 = object.create (person1) ؛ person2.name = "zyj" ؛ person2 zyjconsole.log (person1.friends) ؛ // ["AAA" ، "BBB" ، "CCC"] console.log (person2.friends) ؛ // ["AAA" ، "BBB" ، "CCC"]يمكن اختيار هذا الميراث عندما لا تكون هناك حاجة لتعبئة المُنشئ لإنشائها ، ولكن تريد فقط أن يظل كائنًا مشابهًا لآخر.
الميراث الطفيلي
الميراث الطفيلي هو فكرة مرتبطة ارتباطًا وثيقًا بميراث النموذج الأولي.
فكرة التنفيذ: قم بإنشاء وظيفة تُستخدم فقط لتغليف عملية الميراث ، والتي تعزز الكائن داخليًا بطريقة ما ويعيد أخيرًا الكائن.
functionObj (o) {functionF () {} f.prototype = o ؛ returnnewf () ؛} functionCreatePerson (Original) {// alsapsulate process process farclone = obj (Original) ؛ // إنشاء كائن clone.showsomething = function () {// تعزيز الكائن console.log ("Hello World!") ؛ } ؛ returnclone ؛ // return object} varperson = {name: "percy"} ؛ varperson1 = createPerson (person) ؛ console.log (person1.name) ؛ // percyperson1.showsomething () ؛ // مرحبا بالعالم!الجمع الطفيلي الميراث
دعونا نتحدث أولاً عن أوجه القصور في ميراثنا السابق. أكبر مشكلة في الميراث المركب هي أنه بغض النظر عن الموقف ، سيتم استدعاء مُنشئ الفئة الأم مرتين: الأول هو عند إنشاء النموذج الأولي للكاسفة الفرعية ، والآخر هو عند استدعاء مُنشئ الفئة الفرعية ، ويتم استدعاء مُنشئ الفئة الأم داخل مُنشئ الفئة الفرعية.
functionFather (name ، friends) {this.name = name ؛ this.friends = friends ؛} الأب. تسمى الدعوة الثانية إلى الأب () في الواقع هذا.تجعل المكالمة الأولى النموذج الأولي للفئة الفرعية مثيل للفئة الأصل ، بحيث يحصل النموذج الأولي للكاسورة الفرعية على سمة المثيل للفئة الأصل ؛ ستؤدي المكالمة الثانية إلى الحصول على سمة مثيل الفئة الفرعية أيضًا للحصول على سمة المثيل للفئة الأصل ؛ وستمنع سمة المثيل للكاسورة الفرعية السمات التي يتم تكرارها مع النموذج الأولي للفئة الفرعية افتراضيًا. لذلك ، بعد هاتين المكالمتين ، تظهر السمات غير الضرورية في النموذج الأولي للفئة الفرعية ، وبالتالي إدخال ميراث الجمع الطفيلي لحل هذه المشكلة.
الفكرة وراء الميراث المركب الطفيلي هي: ليست هناك حاجة لاستدعاء مُنشئ الفئة الأصل لتحديد النموذج الأولي للكنيسة الفرعية. كل ما نحتاجه هو نسخة من النموذج الأولي للصف الأصل.
في الأساس ، هو استخدام الميراث الطفيلي لتوفير النموذج الأولي للفئة الأصل ، ثم إعادة النتيجة إلى النموذج الأولي لفئة الطفل.
functionObj (o) {functionf () {} f.prototype = o ؛ returnnewf () ؛} functionInherItPrototype (son ، الأب) {varprototype = obj (poD.Prototype) ؛ // إنشاء Object Ority.Constructor = son ؛ // تعزيز الكائن son.prototype = النموذج الأولي ؛ // return Object} functionFather (name ، friends) {this.name = name ؛ الأب. كول (هذا ، الاسم ، ['aaa' ، 'bbb']) ؛ هذا. "BBB" ، "CCC"] console.log (s1.money) ؛ // 100k $ s1.getName () ؛ // son1s1.getage () ؛ // 12vars2 = newson ('son2' ، 24) ؛ console.log (s2.friends) ؛ // ["aaa" ، "bbb"] console.log (s2.money) ؛ // 100k $ s2.getName () ؛ // son2s2.getage () ؛ // 24المزايا: اجعل النماذج الأولية لجعل الفئة الفرعية تجنب وراثة خصائص المثيل غير الضرورية في فئة الأصل.
يعتقد المطورون عمومًا أن الميراث التوافقي الطفيلي هو طريقة الميراث المثالية القائمة على الميراث النوع.
في النهاية
أخيرًا ، أوصي بشدة بمقالتين صعبة للغاية
JavaScript كيف يعمل الميراث النموذجي حقًا
مخطط الميراث الكلاسيكي من JavaScript (بحاجة إلى عبور الجدار)
التقط صورة صعبة من المقالة الثانية:
بعد قراءته ، أفهم سلسلة النموذج الأولي في ثوان. هل هناك أي شيء؟
ما ورد أعلاه هو جمع المعلومات التي ورثها JavaScript. سنستمر في إضافة المعلومات ذات الصلة في المستقبل. شكرا لدعمكم لهذا الموقع!