العلاقة بين [[النموذج الأولي]] والنموذج الأولي في جافا سكريبت

StackOverflow https://stackoverflow.com/questions/383201

  •  23-08-2019
  •  | 
  •  

سؤال

من http://www.jibbering.com/faq/faq_notes/closures.html. :

ملاحظة: تعرف EcmaScript الخاصية داخليا [[نموذجا أوليا]] من نوع الكائن الداخلي. لا يمكن الوصول إلى هذه الخاصية مباشرة مع البرامج النصية، ولكنها سلسلة الكائنات المشار إليها مع الخاصية الداخلية [[النموذج الأولي] المستخدمة في دقة ملحق العقارات؛ سلسلة النموذج الأولي للكائن. توجد خاصية نموذجية عامة للسماح للتخصيص وتعريف وتلاعب النماذج الأولية بالتعاون مع الممتلكات الداخلية [[النموذج الأولي]]. يتم وصف تفاصيل العلاقة بين الاثنين في ECMA 262 (الطبعة الثالثة) وهي تتجاوز نطاق هذه المناقشة.

ما هي تفاصيل العلاقة بين الاثنين؟ لقد استعرضت من خلال ECMA 262 وكل ما قرأته هناك أشياء مثل:

يمكن الرجوع إلى النموذج الأولي المرتبط بالبناء من قبل منشئ التعبير البرنامجي.

كائنات Ecmascript الأصلية لها خاصية داخلي تسمى [[النموذج الأولي]]. قيمة هذه الخاصية إما لاغية أو كائن وتستخدم في تنفيذ الميراث.

كل وظيفة مدمجة وكل منشئ مدمج لديه كائن النموذج الأولي وظيفة، وهي القيمة الأولية لوظيفة التعبير.

يحتوي كل كائن النموذج المدمج على كائن النموذج الأولي للكائن، وهو القيمة الأولية لكائن التعبير .protineType (15.3.2.1)، كخاصية خاصية Internal [[Prototype]]، باستثناء كائن النموذج الأولي للكائن نفسه.

من هذا كل ما أجمعه هو أن الملكية [[النموذج الأولي] أي ما يعادل prototype الممتلكات إلى حد كبير أي كائن. هل انا مخطئ؟

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

المحلول

أعتقد أنك صحيح في معظم الحالات.

كل كائن لديه مخفي [[Prototype]] الممتلكات، التي تستخدم للميراث. الوظائف بالإضافة إلى ذلك prototype الممتلكات، التي يتم استخدامها فقط عند استخدام الوظيفة كمبني: عند إنشاء كائن باستخدام new, ، ال [[Prototype]] تم تعيين خاصية الكائن الجديد على prototype خاصية الوظيفة التي تم استخدامها كمبنى.

على سبيل المثال

function C() {}
C.prototype = P1;  
var obj = new C();  // obj.[[Prototype]] is now P1.

يمكنك الحصول على [[Prototype]] الممتلكات باستخدام Object.getPrototypeOf(<obj>). وبعد (تم تحديد هذه الطريقة في Ecmascript 5. لا تملك الإصدارات الأقدم من JavaScript أي طريقة قياسية للقراءة [[Prototype]]).

يمكنك مستخدم الوصول إلى النموذج الأولي من خلال المنشئ، على سبيل المثال:

obj.constructor.prototype == Object.getPrototypeOf(obj) 

ولكن هذا ليس هو الحال دائما، حيث يمكن إعادة تعيين خاصية النموذج الأولي لوظيفة المنشئ، ولكن [[Prototype]] لا يمكن إعادة تعيين كائن بعد إنشاء الكائن. لذلك إذا قمت بذلك:

C.prototype = P2;

ومن بعد

obj.constructor.prototype != Object.getPrototypeOf(obj)

لأن النموذج الأولي لل C هو الآن P2, ، لكن [[Prototype]] من obj مازال P1.

لاحظ أنه فقط الوظائف التي لها prototype خاصية. لاحظ أيضا أن prototype خاصية وظيفة ليست هي نفسها [[Prototype]] خاصية وظيفة!

نصائح أخرى

للإجابة على سؤالك مباشرة: منطقيا هي نسخة خاصة للكائن prototype خاصية منشئتها. باستخدام MetaLanguage هذه هي الطريقة التي يتم بها إنشاء الكائنات:

// not real JS

var Ctr = function(...){...};
Ctr.prototype = {...}; // some object with methods and properties

// the object creation sequence: var x = new Ctr(a, b, c);
var x = {};
x["[[prototype]]"] = Ctr.prototype;
var result = Ctr.call(x, a, b, c);
if(typeof result == "object"){ x = result; }
// our x is fully constructed and initialized at this point

في هذه المرحلة، يمكننا تعديل النموذج الأولي، وسيتم انعكاس التغيير من خلال جميع الكائنات من الفصل، لأنها تشير إلى النموذج الأولي حسب المرجع:

Ctr.prototype.log = function(){ console.log("...logging..."); };

x.log();  // ...logging..

ولكن إذا غيرنا النموذج الأولي على المنشئ، فستستمر كائنات تم إنشاؤها بالفعل في الإشارة إلى الكائن القديم:

Ctr.prototype = {life: 42};
// let's assume that the old prototype didn't define "life"

console.log(x.life);  // undefined
x.log();              // ...logging...

في الاتفاقية الكاملة مع المعيار [[prototype]] غير متوفر، ولكن Mozilla يمتد المعيار __proto__ الممتلكات (للقراءة فقط)، والتي تعرض المخفية عادة [[prototype]]:

تكرارا، __proto__ يمكن تصديقها في المعيار ES3.1 التالي.

بالإضافة إلى إجابة Olavk: بعض تطبيقات JavaScript (على سبيل المثال موزيلا) السماح بالوصول إلى الممتلكات [[prototype]] مباشرة ...

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