سؤال

وأنا أعلم أن هناك الكثير من الأسئلة المشابهة طن من رائع الإجابات على هذا.حاولت أن ننظر إلى الكلاسيكية الميراث الأساليب ، أو تلك إغلاق الطرق وما إلى ذلك.بطريقة ما أنا أعتبر أنها أكثر أو أقل "هاك" الأساليب لي, كما لا حقا ما جافا سكريبت مصممة للقيام به.(نرحب أي شخص تصحيح لي إذا كنت مخطئا).حسنا, طالما أنه يعمل ، أنا استمتع مع الكلاسيكية نمط الميراث مثل:

PARENTClass = function (basevar) { do something here; };
PARENTClass.prototype = { a: b, c: d}; // prototype is auto gen 

// Inheritance goes here
CHILDClass = function (childvar) { do something; };
CHILDClass.prototype = new PARENTClass(*1); // Actual inheritance to the prototype statement
// Instance
CHILDInstance = new CHILDClass(whatever);

أعلاه هو بطريقة أو بأخرى إلى فهم الميراث من JS.ولكن سيناريو واحد ليس لدي أي فكرة عن كيفية تنفيذ هذا ما إذا كنت تريد أن تفعل بعض تهيئة أثناء إنشاء كائن (أي داخل منشئ) ، و وجوه جديدة يمكن استخدامها على الفور....الرسم على المشكلة قد لا تكون واضحة جدا ، لذلك اسمحوا لي أن استخدام ما يلي C# الزائف لشرح ما تريد القيام به:

class PARENT {
    public PARENT (basevar) { ... }
}
class CHILD : PARENT {
    public CHILD (basevar) : PARENT (basevar) // constructor of child, and call parent constructor during construct.
    { ... }
}

لسبب ما (مثل الحرف الأول.عناصر واجهة المستخدم) ، ووضعها في منشئ يبدو أفضل طريقة للقيام به.أي شخص لديه فكرة عن كيف يمكن أن أفعل ذلك.

PS:في *1, ليس لدي أي فكرة ما يجب أن وضعت هناك.PS2:الحالة المذكورة أعلاه لم وجدت مسج.ترث المكتبة يمكن القيام به, أنا فقط أتساءل عما إذا كان لا تستخدم المكتبة يمكن تحقيق ذلك.PS3:أو الفهم الخاطئ.منذ جافا سكريبت وليس المقصود mimick OOP (لهذا السبب أنا أسميها هاك), ما هو "الصحيح" المنطق لتنفيذ هذا.

هل كانت مفيدة؟

المحلول

أنها ليست خلف كما؛ جافا سكريبت هي لغة مبطولة، كما هو محدد ويكيبيديا مثل أين:

..classes غير موجود، وإعادة استخدام السلوك (المعروف باسم الميراث اللغات القائمة على الطبقة) يتم تنفيذها عبر عملية استنساخ الكائنات الموجودة التي تعمل كتاجر النماذج الأولية.

كما يقول، لا تستخدم الفصول في جافا سكريبت. ينحدر كل كائن تنشئته من جافا سكريبت Object; ؛ جميع الكائنات في جافا سكريبت لها prototype كائن، وجميع مثيلات الكائنات التي تقوم بإنشاء طرق وخصائص "ترث" من كائن النموذج الأولي للكائن. ألق نظرة على MDC النموذج المبدئي مرجع كائن لمزيد من المعلومات.

اعتبارا من هذا، عند استدعاء الخط:

CHILDClass.prototype = new PARENTClass();

هذا يسمح لل CHILDClass كائن لإضافة طرق وخصائص كائن النموذج الأولي من PARENTClass الكائن، الذي يخلق تأثير مشابه لفكرة الميراث الموجود باللغات المستندة إلى الفصل. منذ prototype يؤثر الكائن على كل مثيل تم إنشاؤه من هذا الكائن، ويسمح ذلك بضربات وخصائص الكائنات الأصل ليكون موجودا في كل مثيل لكائن طفلك.

إذا كنت ترغب في الاتصال ببناء فئة الأم الخاص بك في منشئك من فئة طفلك، فأنت تستخدم JavaScript call وظيفة؛ يتيح لك ذلك الاتصال ببناء فئة الوالد في سياق منشئ الفئة للأطفال، وبالتالي تعيين الخصائص النموذجية النموذجية حديثا في فئة طفلك إلى ما يتم تعيينه كما هو الحال في فئة الوالدين.

أنت أيضا لا تحتاج إلى وضع أي شيء حددته *1, ، نظرا لأن هذا الخط يستخدم فقط لإضافة الأساليب والخصائص إلى كائن النموذج الأولي من فئة الطفل؛ ومع ذلك، ضع في اعتبارك أنه يستدعي منشئ الفئة الأصل، لذلك إذا كانت هناك أي حجج أساسي في تشغيل منشئ الطبقة الأصل، فيجب عليك التحقق من أن هذه موجودة لتجنب أخطاء JavaScript.

نصائح أخرى

يمكنك استدعاء منشئ الوالدي يدويا في منشئ الفئة الفرعية مثل هذا:

CHILDClass = function (basevar) {
  PARENTClass.call(this, basevar);
  // do something;
};

الخدعة هنا تستخدم call الطريقة، التي تتيح لك استدعاء طريقة في سياق كائن مختلف. يرى وثائق call لمزيد من التفاصيل.

لا يحتوي JavaScript على دعم مدمج لتسلسل هرمي الميراث حيث من المفترض أن يتم تمديد النوع من خلال التجميع، أي إضافة الوظائف المطلوبة مباشرة إلى الكائن نفسه أو النموذج الأولي إذا كان سيتم تقاسم الخاصية بين المثيلات.

ومع ذلك، فإن JS قوية بما يكفي لجعل تنفيذ أشكال أخرى من بناء الكائنات الممكنة، بما في ذلك الميراث الكلاسيكي.

نظرا ل وظيفة استنساخ - وهو ما يكفي لإضافة الميراث النموذجي "الحقيقي"، وليس عنباة JavaScript الخاصة به - يمكن تنفيذ Exampe الخاص بك مثل هذا:

function ParentClass(baseVar) {
    // do stuff
}

// don't overwrite the prototype object if you want to keep `constructor`
// see http://joost.zeekat.nl/constructors-considered-mildly-confusing.html
ParentClass.prototype.a = 'b';
ParentClass.prototype.c = 'd';

function ChildClass(childVar) {
    // call the super constructor
    ParentClass.call(this, childVar);
}

// don't inherit from a ParentClass instance, but the actual prototype
ChildClass.prototype = clone(ParentClass.prototype);
ChildClass.prototype.e = 'f';

من الممكن أيضا إضافة بعض السكر النحوي للميراث في الفصل - التنفيذ الخاص بي يمكن العثور عليها هنا.

المثال من أعلاه سوف تقرأ بعد ذلك

var ParentClass = Class.extend({
    constructor: function(baseVar) {
        // do stuff
    },
    a: 'b',
    c: 'd'
});

var ChildClass = ParentClass.extend({
    e: 'f'
});

لدي غلاف منفاخ JavaScript OOP خفيف الوزن يوفر ميراث "تشبه الفئة" حيث يمكنك تجاوز الأساليب الأساسية أو منشئ الأساس أو الأعضاء.

تحدد فصولك مثل هذا:

//Define the 'Cat' class
function Cat(catType, firstName, lastName)
{
    //Call the 'Animal' constructor.
    Cat.$baseNew.call(this, firstName, lastName);

    this.catType = catType;
}
//Extend Animal, and Register the 'Cat' type.
Cat.extend(Animal, { type: 'Cat' }, {
    hello: function(text)
    {
        return "meaoow: " + text;
    },
    getFullName: function()
    {
        //Call the base 'Animal' getFullName method.
        return this.catType + ": " + Cat.$base.getFullName.call(this);
    }
})

//It has a built-in type system that lets you do stuff like:

var cat = new Cat("ginger", "kitty", "kat");
Cat.getType()                     // "Cat"
cat.getBaseTypesAndSelf()         // ["Cat","Animal","Class"]
cat.getType()                     // "Cat"
cat.isTypeOf(Animal.getType())    // "True"

var dynamicCat = Class.createNew("Cat", ["tab","fat","cat"])
dynamicCat.getBaseTypesAndSelf()  // ["Cat","Animal","Class"]
dynamicCat.getFullName()          // tab: fat cat

شفرة المصدر المتاحة في: class.js.

لدي أيضا المزيد من التفاصيل في مدونتي oop في جافا سكريبت

مجرد التفكير أود أن أذكر بعض المسائل مع النمط الكلاسيكي أنت ذاهب ل:

  1. إشارة فأر على فئة سوبر(es) سوف تكون متاحة أساسا السكون على جميع الحالات.على سبيل المثال, إذا كان لديك var arr = [1,2,3] في السوبر ، والقيام instance_1.آر.دفع(4) instance_2.آر.دفع(5) كل من هذه الحالات "سوف نرى" التغييرات.
  2. حتى حل 1.مع أيمن الحل الذي Zakas يدعو "منشئ سرقة", ولكن الآن يمكنك استدعاء منشئ مرتين:مرة واحدة على النموذج الخاص بك ومرة منشئ سرقة.حل - عن النموذج الخاص بك استخدام مساعد مثل inheritPrototype (لقد أظهرت تنفيذ كامل هذا في هذا المنصب: inheritPrototype طريقة FWIW, هذا الأساس جاءت من مجموعة من الصفحة 181 من Zakas كتاب و بعض Crockford الدراسة.

  3. لا الخصوصية (ولكن بعد ذلك مرة أخرى, كنت بحاجة إلى استخدام شيء من هذا القبيل دائم كائن نمط للحصول على هذا و هذا قد لا يكون ما تريد)

  4. وجوه التعريف اليسار "التعلق":الحل - وضع إذا كان البيان التحقق من أي من النموذج الخاص بك وظائف ومن ثم تحديد النموذج مع النموذج الحرفي.

يجب تشغيل أمثلة من كل هذا على جيثب!!!

كان مجرد قدر من التحدي بالنسبة لي حقا جروك كل من:Zakas و Crockford الكتب على إنشاء الكائن و الميراث.أنا في حاجة أيضا إلى محاولة بعض مختلفة جافا سكريبت TDD الأطر.لذلك قررت إنشاء مقال على كل TDD الأطر جافا سكريبت إنشاء كائن & الميراث.وقد تشغيل رمز jspec الاختبارات!وهنا الرابط:* بلدي جيثب مفتوحة المصدر مقال/الكتاب

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top