مقدمة
رأيت سؤالًا كهذا على SegmentFault:
var f = function () {} ؛ object.prototype.a = function () {} ؛ function.prototype.b = function () {} ؛ var f = new f () ؛س: هل يمكن لـ F الحصول على A و B؟ ما هو المبدأ؟
للوهلة الأولى ، كنت في حيرة من أمري. بعد دراسة متأنية ، وجدت أنني ما زلت لم أفهم النموذج الأولي تمامًا ، لذلك قمت بتلخيصه وملأت حفرة ~
وظيفة والكائن
قبل حل المشكلة ، دعنا نتحدث عن النموذج الأولي ، وسلسلة النموذج الأولي ، والعلاقة بين الوظيفة والكائن ، وهو أيضًا محور هذه المقالة.
النموذج الأولي
عند إنشاء وظيفة ، سيتم إنشاء كائن النموذج الأولي تلقائيًا لذلك ، والذي يمكن الوصول إليه من خلال خاصية النموذج الأولي للوظيفة.
قم بإنشاء كائن مثيل للمُنشئ ، والذي سيحتوي على مؤشر (خاصية داخلية) بداخله ، مشيرًا إلى كائن النموذج الأولي للمركين. ECMA-262 تسمى الطبعة الخامسة من هذا المؤشر [[النموذج الأولي]]. على الرغم من عدم وجود طريقة قياسية للوصول إلى [[النموذج الأولي]] في البرامج النصية ، تدعم Firefox و Safari و Chrome خاصية __proto__ على كل كائن للوصول إلى كائن النموذج الأولي الخاص بموفرها.
دعني أقول شيئًا مهمًا مرة أخرى:
يقوم المُنشئ بالوصول إلى كائن النموذج الأولي من خلال خاصية النموذج الأولي.
يقوم كائن المثيل بالوصول إلى كائن النموذج الأولي من خلال السمة الداخلية [[[[النموذج الأولي]] ، ويقوم المتصفح بتنفيذ سمة _proto_ لكائن المثيل للوصول إلى كائن النموذج الأولي.
var f = function () {} ؛ var f = new f () ؛ // على افتراض أن كائن النموذج الأولي لـ f هو p ، ثم // f.prototype === p ؛ // f .__ proto__ === p ؛كرر مرة أخرى. . يشير النموذج الأولي إلى العلاقة بين المنشئ وكائن النموذج الأولي ، ويشير __proto__ إلى العلاقة بين كائن المثيل وكائن النموذج الأولي.
سلسلة النموذج الأولي
يرث الفئة A B ، B يرث C ... في الواقع ، هناك كائن النموذج الأولي مع مؤشر يشير إلى B في كائن النموذج الأولي لكائن A ، وكائن النموذج الأولي مع مؤشر يشير إلى C في كائن النموذج الأولي ... لاحظ أنه هو العلاقة بين كائنات النموذج الأولي. لا توجد علاقة بين منشئو ABC الثلاثة ، لذلك يطلق عليها "سلسلة النموذج الأولي" ~
على افتراض A هو كائن مثيل لـ A ، يتم عرض سلسلة النموذج الأولي لـ A في الخط الأرجواني في الشكل أدناه ، ويقوم الخط البرتقالي بتوصيل المنشئ وكائن النموذج الأولي.
كما يتضح من الشكل ، فإن نهاية سلسلة النموذج الأولي هي كائن. عند البحث عن خاصية أو طريقة ، ابحث أولاً عما إذا كانت نفسها لديها أم لا. إذا لم يكن الأمر كذلك ، فابحث على طول سلسلة النموذج الأولي حتى يتم العثور عليها أو إرجاعها أخيرًا إلى غير محدد بعد فارغ.
وظيفة والكائن
العلاقة بين الوظيفة والكائن متشابكة بعض الشيء:
الكائن مُنشئ. نظرًا لأنها وظيفة ، فهي كائن مثيل الوظيفة ؛ الوظيفة هي مُنشئ ، ولكن النموذج النمط هو كائن. نظرًا لأنه كائن ، فهو كائن مثيل للكائن.
جميع الكائنات هي مثيلات للكائن ، وجميع الوظائف هي حالات الوظيفة.
الكائن هو مثيل للدالة ، و function.prototype هو مثيل للكائن.
تظهر العلاقة بين الاثنين في الشكل أدناه.
كما يمكن أن ينظر ، الكائن كمؤسس ، فإنه يحتوي على سمة النموذج الأولي الذي يشير إلى Object.prototype ، وككائن مثيل ، يكون له كائن .__ proto__ يشير إلى function.prototype. الوظيفة عبارة عن مُنشئ ، وله سمة نموذجية تشير إلى الوظيفة. النمط النمط ، والوظيفة هي وظيفة ، وهي أيضًا مثيل للوظيفة ، لذلك يكون لها وظيفة .__ proto__ تشير إلى الوظيفة.
يمكن التحقق منه تحت وحدة التحكم Chrome ، كما هو موضح في الشكل.
تحليل السؤال الأصلي
أفضل طريقة لحل مشكلة سلسلة النموذج الأولي هي رسم صورة. بعد التحليل السابق ، لا ينبغي أن تكون هذه الصورة مشكلة ، على النحو التالي ~
يتم رسم سلسلة النموذج الأولي لـ F بواسطة خط أزرق ، بحيث يمكن لـ F الوصول إلى A ، لكن B لا يمكن الوصول إليها.
إذا لم ترسم صورة ، للوهلة الأولى ، فقد تعتقد أنه يمكن لـ F الوصول إلى ب. قد يكون مثلي أن F.Prototype يشير إلى الوظيفة. النموذج ، ولكن في الواقع ، فإن النمط f.prototype هو كائن وليس وظيفة ، لذلك لن يكون كائن النموذج الأولي الخاص به وظيفة.
لذلك ، يجب أن ترسم صورة كلما كانت مشكلة سلسلة النموذج الأولي ~
موضوع ممتد
في السؤال أعلاه ، يمكن لـ F الوصول إلى A ، ولكن ليس ب. ولكن يمكن للوصول إلى كل من A و B. إذا قمت بتعديل السؤال إلى ما يلي ، فما هي نتيجة FB ()؟ لماذا؟ يمكنك التفكير في الأمر ~
var f = function () {} ؛ object.prototype.a = function () {} ؛ function.prototype.b = function () {console.log ('f .__ proto__')} ؛ f.prototype.b = function () {console.log ('f.prototype') ؛} ؛لخص
بعد قراءة هذا ، هل وجدت ميزة خاصة للوظيفة؟
بالنسبة للكائن العام ، لا يوجد سوى سمة __proto__ واحدة تستخدم للوصول إلى كائن النموذج الأولي لملعبه ، وبالنسبة للدالة ، فهي وظيفة وكائن.
كدالة ، يولد مع سمة النموذج الأولي تشير إلى اسم وظيفة كائن النموذج الأولي.
ككائن مثيل للدالة ، فإنه يحتوي على سمة __proto__ التي تشير إلى وظيفة
عادةً ما تشير هذين الخصائصان إلى كائنين ، ولكن كلا من خصائص الوظيفة تشير إلى نفس الوقت ، كلاهما يشيران إلى function.prototype.
بالنسبة للوظيفة A () ، فإن الأساليب في النمط A.Protype هي للاتصال بكائن مثيلها ولن يتم استخدامها بمفردها ؛ عندما يتم تشغيل A كمثيل ، يتم استدعاء الطرق في .__ proto__. بمعنى آخر ، عند استخدامه كمؤسسة ، يتم أخذ سلسلة النمط A.Protype ، ويتم تعيين الأساليب والسمات على أمثلةها ؛ عند استخدامها ككائن ، يتم أخذ سلسلة A.__ proto__. في سيناريوهات مختلفة ، ليس من الخطأ تمييز هويتها.
بعد المقالة بأكملها ، أشعر أن ما قلته يزعجه تمامًا ... يرجى تصحيحني إذا كانت هناك أي أوجه قصور - أما بالنسبة للسؤال ، فأنا لا أعرف حقًا ما أسميه. .
قد تجلب لك هذه المقالة بعض المكاسب بعد قراءتها ~ ^_ ^
شكرا لك على دعمك لهذا الموقع. سنستمر في تحديث المعلومات ذات الصلة في المستقبل لمساعدتك في تعلم وفهم هذا الجزء من المعرفة!