على الرغم من أن JavaScript هي لغة موجهة نحو الكائن ، إلا أن آلية الميراث كانت مختلفة عن اللغات التقليدية الموجهة للكائنات الأخرى منذ بدايتها. إنها آلية ميراث قائمة على النموذج الأولي. ومع ذلك ، في ظل هذه الآلية ، لا تزال هناك بعض طرق التنفيذ المختلفة للميراث.
الطريقة 1: الميراث الكلاسيكي
يشير ما يسمى بالميراث الطبقي إلى تقليد طريقة الميراث للغات التقليدية الموجهة للكائنات. كل من الميراث والأطراف الموروثة هي "فصول". الرمز كما يلي:
حدد أولاً فئة أولياء الأمور (أو الطبقة الفائقة):
وظيفة الشخص (الاسم) {this.name = name ؛ } person.prototype.getName = function () {return this.name ؛ } ؛يتم تعريف سمات شخص الفئة الأصل في المُنشئ ، والتي يمكن أن تضمن أن سمة اسم الفئة الفرعية لا تشارك هذه السمة معها ، ولكنها تنتمي إلى الفئة الفرعية بشكل منفصل. يتم تثبيت طريقة getName على النموذج الأولي من أجل السماح بمثيلات متعددة من الفئة الفرعية التي ترثها بمشاركة هذه الطريقة ، بحيث يمكن حفظ الذاكرة (بالنسبة لحالات متعددة ، في كل مرة يخرج فيها مثيل جديد ، فإنه يضمن أن طريقة GetName لهذه الحالات تشير إلى نفس مساحة الذاكرة ، بدلاً من مساحة مستقلة).
تحديد طريقة الميراث تمتد ، على النحو التالي:
وظيفة تمديد (الفئة الفرعية ، الفئة الفائقة) {var f = function () {} ؛ f.prototype = superclass.prototype ؛ subcleass.prototype = new f () ؛ subcleass.prototype.constructor = فئة فرعية ؛ الفئة الفرعية. if (superclass.prototype.constructor == object.prototype.constructor) {superclass.prototype.constructor = superclass ؛ }}في هذه الطريقة ، قم أولاً بإنشاء فئة F جديدة F ، دع النموذج الأولي له النموذج الأولي للفئة الأصل ، واترك النموذج الأولي للكنيسة الفرعية يشير إلى مثيل للفئة F ، وبالتالي تحقيق غرض وراثة الفئة الأصل. في الوقت نفسه ، نظرًا لأن النموذج الأولي للفئة الفرعية يتم تعديله ، فإن سمة مُنشئ النموذج الأولي المعدلة تُشار إلى الفئة الفرعية ، بحيث يكون لها وظيفة مُنشئ ، وفي الوقت نفسه ، يمكن للفئة الفرعية تثبيت سمة فئة فائقة. يمكن للفئة الفرعية استدعاء الفئة الأصل من خلال هذه الخاصية ، وبالتالي إنشاء العلاقة بين الفئة الفرعية والفئة الأم.
حدد مؤلفًا من الفئة الفرعية بروث الشخص من الفئة الأصل ، على النحو التالي:
مؤلف الوظيفة (الاسم ، الكتب) {uphur.superclass.constructor.call (هذا ، الاسم) ؛ this.book = كتب ؛ } تمديد (مؤلف ، شخص) ؛ uptor.prototype.getBooks = function () {return this.book ؛ }هنا ، يتم استدعاء مُنشئ الفئة الأصل من خلال سمة الفئة الفائقة في مُنشئ الفئة الفرعية. في الوقت نفسه ، يتم استخدام طريقة المكالمات لتحويل مؤشر مكالمة الطريقة ، بحيث يكون للمؤلف الفرعي أيضًا (يرث) خصائص فئة الأصل ، والفئة الفرعية لديها أيضًا كتاب السمات الخاص به. لذلك ، يتم تعيين كتب المعلمات لكتاب السمات في المنشئ لتحقيق الغرض من البناء. استخدم وظيفة التمديد لتربير الخصائص والأساليب على النموذج الأولي للطبقة الأصل (في الواقع ، يتم ورث الأساليب فقط ، لأننا قمنا بتركيب طرق النموذج الأولي من قبل ، ويتم تحديد الخصائص في المنشئ). في الوقت نفسه ، يكون للمؤلف أجهزة GetBooks الخاصة بالأسلوب الخاص به ، حيث يتصاعدها على النموذج الأولي المقابل ، مما يحقق الغرض من توسيع نفسه على أساس الميراث.
من الواضح أن طريقة الميراث هذه هي نوع من الميراث المشابه للغة التقليدية الموجهة للكائن. الميزة هي أنه من السهل على المبرمجين الذين اعتادوا على المفهوم التقليدي الموجهة للكائنات. العيب هو أن العملية مرهقة نسبيًا واستهلاك الذاكرة أكبر قليلاً ، لأن الفئة الفرعية لها أيضًا مُنشئها ونموذجها الأولي ، وأن سمات الفئة الفرعية والفئة الأصل معزولة تمامًا. حتى لو كان الاثنان من نفس القيمة ، فلن يتمكنوا من مشاركة نفس الذاكرة.
الطريقة 2: ميراث النموذج الأولي
أولاً ، حدد فئة الوالدين. هنا لن نقلد عن عمد استخدام المُنشئين لتحديده ، ولكن تحديد كائن ما في شكل حرفي كائن ، وهو فئة الوالدين
var person = {name: 'name default' ، getName: function () {return this.name ؛ }} ؛مثل الطريقة الأولى ، يحتوي الكائن على اسم خاصية وطريقة getName.
ثم حدد طريقة الاستنساخ لتنفيذ ميراث الفئة الفرعية إلى الفئة الأصل ، على النحو التالي:
دالة استنساخ (obj) {function f () {} f.prototype = obj ؛ إرجاع جديد f () ؛ }تقوم طريقة الاستنساخ بإنشاء كائن جديد ، ويشير إلى النموذج الأولي للكائن إلى الفئة الأصل ، أي المعلمة OBJ ، ويعيد الكائن في نفس الوقت.
أخيرًا ، ترث الفئة الفرعية فئة الأصل من خلال وظيفة الاستنساخ ، على النحو التالي:
var upump = clone (شخص) ؛ uptor.book = ['javaScript'] ؛ uptor.showbook = function () {return this.book ؛ }هنا يتم تعريف الفئة الفرعية ، ويرث شخص الفئة الأصل من خلال وظيفة الاستنساخ ، ويتم توسيع دفتر السمات ، ويتم توسيع دفتر العرض. هنا ، تحتوي الفئة الفرعية أيضًا على اسم السمة ، ولكنها نفس قيمة اسم الفئة الأصل ، لذلك لا يتم تجاوزها. إذا كان الأمر مختلفًا ، فيمكنك استخدامه.
المؤلف. name = 'new name' ؛ الكتابة فوق هذه الخاصية للحصول على قيمة سمة الاسم الجديدة للكاسورة الفرعية.
هذا الميراث النموذج الأولي أبسط وأكثر طبيعية من الميراث الطبقي. في الوقت نفسه ، إذا كانت سمات الفئة الفرعية وقيم سمة الفئة الأصل هي نفسها ويمكن تعديلها ، فهي تشترك بالفعل في نفس مساحة الذاكرة. على سبيل المثال ، يصعب فهم سمة الاسم أعلاه للمبرمجين الذين اعتادوا على البرامج التقليدية الموجهة للكائنات. إذا تم اختيار الاثنين ، فإن هذه الطريقة أفضل بلا شك.
نظرًا لأن JavaScript يتبنى نهجًا قائمًا على النموذج الأولي لتنفيذ الميراث ، ويمكن للنموذج الأولي لكل كائن أن يشير فقط إلى مثيل لفئة معينة (وليس إلى حالات متعددة) ، وكيفية تنفيذ الميراث المتعدد (أي ، دع الفئة لديها طرق وسمات لفئات متعددة في نفس الوقت ، ولا تحدد هذه الأساليب والسمات نفسها داخليًا)؟
في نمط تصميم JavaScript ، يتم إعطاء فئة Mixin:
أولاً ، حدد فئة المنشطات لحفظ بعض الأساليب والسمات الشائعة الاستخدام. يمكن إضافة هذه الطرق والسمات إلى أي فئة أخرى من خلال التوسع ، بحيث يكون للفئة المضافة طرق وسمات معينة للفئة. إذا تم تعريف فئات المنشطات المتعددة وإضافتها إلى فئة في نفس الوقت ، فإن الفئة تنفذ بشكل غير مباشر "الميراث المتعدد". بناءً على هذه الفكرة ، فإن التنفيذ هو كما يلي:
تعريف الطبقة المهيمنة على العناصر:
var mixin = function () {} ؛ mixin.prototype = {serialize: function () {var output = [] ؛ لـ (المفتاح في هذا) {output.push (key+":"+this [key]) ؛ } الإرجاع. join ('،') ؛ }}تحتوي فئة المنشطات على طريقة تسلسل تستخدم لاجتياز نفسها ، وإخراج سماتها وقيم السمات الخاصة بها ، وإعادتها كسلاسل ، مفصولة بفواصل.
تحديد طريقة التوسع لجعل فئة لها سمات أو طرق لفئة متعددة المجموعات بعد التوسع ، على النحو التالي:
دالة mupment (atsiveClass ، GiveClass) {if (الوسيطات [2]) {for (var i = 2 ، len = edation.length ؛ i <len ؛ i ++) {receivingclass.prototype [encuments [i]] = giveClass.Prototype [endressuments [i]] ؛ }} else {for (methodName in giveClass.Prototype) {if (! atsiveclass.prototype [methodName]) {receivingClass.Prototype [methodName] = GiveClass.Prototype [methodName] ؛ }}}}تحتوي هذه الطريقة على معلمتين بشكل افتراضي. تقبل المعلمة الأولى الفئة الموسعة ، والمعلمة الثانية هي الفئة المخدر (المستخدمة لتوسيع الفئات الأخرى) ، ويمكن أن تكون هناك معلمات أخرى. إذا كانت أكبر من معلمتين ، فإن المعلمات اللاحقة هي أسماء الأسلوب أو السمات ، والتي يتم استخدامها للإشارة إلى أن الفئة الموسعة تريد أن ترث السمات أو طرق الفئة المخدر. خلاف ذلك ، فإن جميع السمات وطرق الفئة المخدرات ورثت افتراضيا. في هذه الوظيفة ، تم استخدام الفرع الأول لروث السمات والأساليب المحددة ، والفرع الآخر هو الحالة التي يتم فيها ترجيح جميع السمات والأساليب افتراضيًا. يتمثل جوهر هذه الطريقة في توسيع (إضافة) الخصائص والأساليب على النموذج الأولي لفئة تعاطي المنشطات إلى النموذج الأولي للفئة الموسعة ، بحيث تحتوي على خصائص وطرق لفئة تعاطي المنشطات.
أخيرًا ، استخدم طريقة التوسع لتحقيق ميراث متعدد
زيادة (مؤلف ، Mixin) ؛ var upludle = new upluct ('js' ، ['JavaScript Design Patterns']) ؛ تنبيه (مؤلف.هنا فئة من المؤلف. يرث هذا الفصل من فئة الوالدين للشخص ويحتوي أيضًا على أساليب وخصائص من فئة Metabolized Mixin. إذا أردت ، يمكنك تحديد الفصول المستقلبات لتوسيع الفصل. يمكن أن يرث أيضًا خصائص وطرق الفئات الأخرى المستقرة التي تحددها ، بحيث يتم تحقيق الميراث المتعدد. أخيرًا ، تكون نتيجة تشغيل طريقة تسلسل المؤلف كما يلي:
ستجد أن هذا الفصل له خصائص وطرق فئة الشخص وفئة المؤلف وفئة Mixin. يتم الحصول على خصائص وطرق الشخص والمواصفات من خلال "الميراث". في الواقع ، فإنه يدرك الميراث المتعدد.