في معظم لغات البرمجة ، هناك فصول وكائنات ، ويمكن لفئة واحدة أن ترث فصول أخرى.
في JavaScript ، يعتمد الميراث على النموذج الأولي ، مما يعني أنه لا توجد فئات في JavaScript ، وبدلاً من ذلك يرث كائن واحد كائنًا آخر. سائدا
1. الميراث ، البروتو
في JavaScript ، عندما يرث كائن أرنب حيوانًا آخر ، فهذا يعني أنه سيكون هناك خاصية خاصة في كائن الأرنب: الأرنب. __ proto__ = Animal ؛
عند الوصول إلى كائن أرنب ، إذا لم يتمكن المترجم المترجم
سمة __proto__ في الكستناء لا يمكن الوصول إليها إلا في Chrome و Firefox. يرجى الاطلاع على الكستناء:
var animal = {eats: true} var rabbit = {Jumps: true} rabbit .__ proto__ = animal // erneritert (rabbit.eats) // trueيتم الوصول إلى سمة EATS من كائن حيوان.
إذا تم العثور على السمة في كائن الأرنب ، فلن يتم فحص سمة proto.
دعنا نمتلك كستناء آخر. عندما يكون هناك أيضًا سمة EATS في الفئة الفرعية ، فلن يتم الوصول إلى فئة الأصل.
var animal = {eats: true} var veduprabbit = {eats: false} feduprabbit .__ proto__ = Animal Alert (feduprabbit.eats) // falseيمكنك أيضًا إضافة وظيفة بالحيوان ، ويمكن الوصول إليها أيضًا في الأرنب.
var animal = {eat: function () {alert ("أنا ممتلئ") this.full = true}} var rabbit = {Jump: function () { / * شيء * /}} rabbit .__ proto__ = Animal(1) Rabbit.EAT ():
يتم تنفيذ وظيفة rabbit.eat () في الخطوتين التاليتين:
أولاً ، يبحث المترجم عن الأرانب. لا توجد وظيفة تناول الطعام في الأرنب ، لذلك تبدو على طول الأرنب. __ proto__ ووجدها بالحيوان.
تعمل الوظيفة مع هذا = الأرنب. هذه القيمة لا علاقة لها بسمات __proto__.
لذلك هذا. full = صحيح في الأرنب:
دعونا نرى ما هي الاكتشافات الجديدة التي قمنا بها هنا. كائن يستدعي وظيفة الأصل ، لكن هذا لا يزال يشير إلى الكائن نفسه ، وهو الميراث.
يُطلق على الكائن المشار إليه بواسطة __proto__ النموذج الأولي ، والحيوان هو النموذج الأولي للأرنب (ملاحظة المترجم: هذه هي سمة __proto__ للأرنب تشير إلى سمة النموذج الأولي للحيوان)
(2) ابحث عند القراءة ، وليس عند الكتابة
عند قراءة كائن ، مثل هذا.
عند تعيين قيمة السمة ، مثل هذا. prop = القيمة ، فلا يوجد سبب للبحث ، وسيتم إضافة هذه السمة (Prop) مباشرة إلى هذا الكائن (هذا هو). حذف OBJ.Prop متشابه ، فإنه يحذف فقط خصائص الكائن نفسه ، وتبقى الخصائص في النموذج الأولي سليمة.
(3) حول بروتو
إذا كنت تقرأ الدليل ، فإننا ندعو هنا __proto__ ، والتي يتم تمثيلها في الدليل باسم [[النموذج الأولي]]. كلا الأقواس مهمة لأن هناك خاصية أخرى تسمى النموذج الأولي.
2. object.create ، object.getPrototypeof
__proto__ هي خاصية غير قياسية توفرها Chrome/Firefox ولا تزال غير مرئية في المتصفحات الأخرى.
جميع المتصفحات الحديثة باستثناء الأوبرا (أي> 9) تدعم وظيفتين قياسيتين للتعامل مع مشاكل النموذج الأولي:
Object.ceate (Prop [، Props])
قم بإنشاء كائن فارغ مع البروتو المعطى:
var animal = {eats: true} rabbit = object.create (Animal) Alert (rabbit.eats) // trueالرمز أعلاه ينشئ كائن أرنب فارغ ويتم تعيين النموذج الأولي على الحيوان
بعد إنشاء كائن الأرنب ، يمكننا إضافة خصائص إليه:
var animal = {ats: true} rabbit = object.create (Animal) rabbit.jumps = trueالمعلمة الثانية لوظيفة الكائن. تم حذف هذا بسبب ميراث علاقتنا.
(1) Object.getProtypeof (OBJ)
إرجاع قيمة OBJ .__ proto__. هذه الوظيفة قياسية ويمكن استخدامها في المتصفحات التي لا يمكنها الوصول مباشرة إلى سمة __proto__.
var animal = {eats: true} rabbit = object.create (Animal) Alert (object.getProtypeof (Rabbit) === Animal) // trueتسمح المتصفحات الحديثة بقراءة قيم السمة __proto__ ، ولكن لا يمكن تعيينها.
3. النموذج الأولي
هناك بعض طرق المستعرض المتقاطع الجيدة لتعيين سمة __proto__ ، والتي ستستخدم وظائف المنشئ. يتذكر! أي وظيفة تنشئ كائن من خلال الكلمة الرئيسية الجديدة.
الكستناء:
دالة الأرنب (الاسم) {this.name = name} var rabbit = New Rabbit ('John') Alert (Rabbit.name) // Johnتقوم العملية الجديدة بتعيين خصائص النموذج الأولي على خاصية __proto__ لكائن الأرنب.
دعونا نلقي نظرة على مبدأها ، على سبيل المثال ، كائن أرنب جديد يرث الحيوان.
var animal = {eats: true} وظيفة الأرنب (الاسم) {this.name = name} rabbit.prototype = Animalvar Rabbit = New Rabbit ('John') ALERT (Rabbit.eats) // true ، لأن الأرنب .__ proto__ == Animalrabbit.prototype = الوسائل الحرفية الحيوانية: تعيين __proto__ = حيوان لجميع الأشياء التي أنشأها أرنب جديد
4.
Object.create (Prop) وظيفة قوية لأنها تسمح الميراث المباشر من كائن معين. يمكن محاكاةه بواسطة الكود التالي:
دالة مورث (proto) {function f () {} f.prototype = proto return new f}إن الوراثة (حيوان) تعادل تمامًا للكائن. إنشاء (حيوان) ، وإرجاع كائن فارغ ، والكائن .__ proto__ = Animal.
الكستناء:
var animal = {eats: true} var rabbit = errant (Animal) Alert (rabbit.eats) // truealert (rabbit.hasownproperty ('Eats')) // false ، from ortyptyدعونا نلقي نظرة على ماهية مبدأها:
دالة مورث (proto) {function f () {} // (1) f.prototype = proto // (2) return new f () // (3)}(1) تم إنشاء وظيفة جديدة ، ولم تضع الوظيفة أي سمات على هذا ، لذلك ستنشئ "FEL NEW F` كائنًا فارغًا.
(2) تم تعيين `f.prototype" على proto
(3) `new` f ينشئ كائن فارغ ، الكائن` __proto__ = f.prototype`
(4) بنغو! نحصل على كائن فارغ يرث "proto"
تستخدم هذه الوظيفة على نطاق واسع في مختلف المكتبات والأطر.
وظيفتك تقبل كائن مع خيارات
/ * الخيارات تحتوي على إعدادات القائمة: العرض ، ارتفاع ، إلخ */قائمة الوظائف (خيارات) {// ...} تريد تعيين قائمة بعض الخيارات (الخيارات) {Options.width = Options.width || 300 // تعيين القيمة الافتراضية // ...}. . . لكن تغيير قيمة المعلمة قد ينتج عنه بعض النتائج الخاطئة ، حيث يمكن استخدام الخيارات في التعليمات البرمجية الخارجية. يتمثل الحل في استنساخ كائن الخيارات ، ونسخ جميع السمات إلى كائن جديد ، وتعديله في الكائن الجديد.
كيف تحل هذه المشكلة مع الميراث؟ يمكن أن تضيف خيارات PS إعدادات ، ولكن لا يمكن حذفها.
حل
يمكنك أن ترث الخيارات وتعديل أو إضافة خصائص جديدة في فئتها الفرعية.
دالة الوراثة (proto) {function f () {} f.prototype = proto return new f} function menu (خيارات) {var opts = inheriT (Options) opts.width = opts.width || 300 // ...}جميع العمليات صالحة فقط في الكائنات الفرعية. عندما تنتهي طريقة القائمة ، لا يزال بإمكان الرمز الخارجي استخدام كائنات الخيارات غير المعدلة. حذف العملية مهمة جدا هنا. إذا كان العرض خاصية في نموذج أولي ، فلن يكون لحذف opts.width أي تأثير
5. Hasownproperty
جميع الكائنات لها وظيفة hasownproperty ، والتي يمكن استخدامها لاكتشاف ما إذا كانت الخاصية نفسها أو نموذج أولي.
الكستناء:
وظيفة Rabbit (name) {this.name = name} rabbit.prototype = {ats: true} var rabbit = new Rabbit ('John') ALERT (Rabbit.hasownproperty ('Eats'))6. حلقة مع/بدون خصائص موروثة
لـ .. في حلقة يخرج جميع خصائص كائن ، بما في ذلك النموذج الأولي الخاص به.
دالة Rabbit (name) {this.name = name} rabbit.prototype = {eats: true} var rabbit = new rabbit ('John') for (var p in rabbit) {Alert (p + "=" + rabbit [p]) // يخرج كلا الاسم "و" يأكل "}استخدم hasownproperty لتصفية خصائص الكائن:
دالة Rabbit (name) {this.name = name} rabbit.prototype = {ats: true} var rabbit = new rabbit ('John') for (var p in rabbit) {if (! rabbit.hasownproperty (p)) تابع // filter out "يأكل" تنبيه (p + "=" + ".7. ملخص
JavaScript ينفذ الميراث من خلال بروتو السمة الخاصة
عند الوصول إلى خصائص الكائن ، إذا لم يتمكن المترجم المترجم في الكائن ، فسوف يستمر في البحث عن خصائص الوظيفة ، وهذا يشير إلى الكائن ، وليس النموذج الأولي الخاص به.
تعيين obj.prop = القيمة ، حذف obj.prop
إدارة البروتو:
يمكن لـ Chrome و Firefox الوصول مباشرة إلى سمة __proto__ للكائن. تدعم معظم المتصفحات الحديثة الوصول إلى القراءة فقط باستخدام Object.getPrototypeof (OBJ).
يمكن لـ Object.Create (proto) إنشاء كائنات طفل فارغة مع البروتو المعطى ، أو تحقيق نفس الوظيفة من خلال الكود التالي:
دالة مورث (proto) {function f () {} f.prototype = proto return new f ()}طرق أخرى:
لـ .. في حلقة يخرج جميع خصائص كائن ما (بما في ذلك النموذج الأولي ونموذجه) وسلسلة النموذج الأولي للكائن.
إذا كان دعامة خاصية تنتمي إلى الكائن OBJ ، فسيتم إرجاع OBJ.HasownProperty (Prop) بشكل صحيح ، وإلا فاشلاً.