في JavaScript، الوظيفة هي كائن من النوع Function
يحتوي على خصائص وطرق. النموذج الأولي (Prototype)
هو سمة لكائن نوع Function
.
يتم تضمين سمة prototype
عند تعريف الوظيفة، وتكون قيمتها الأولية عبارة عن كائن فارغ. لا يوجد نوع نموذج أولي محدد للوظائف في JavaScript، لذلك يمكن أن يكون النموذج الأولي من أي نوع.
يتم استخدام النموذج الأولي لحفظ الخصائص والأساليب المشتركة للكائن . ولا تؤثر خصائص وأساليب النموذج الأولي على خصائص وأساليب الوظيفة نفسها.
// خصائص نوع الوظيفة -> الخصائص التي تحتوي عليها جميع الوظائف console.log(Function.prototype); //[Function] // تحديد الوظيفة fn() { console.log("هذه هي الوظيفة"); } // القيمة الافتراضية للنموذج الأولي هي الكائن الفارغ console.log(fn.prototype); //fn {}; // تحتوي الدالة على مُنشئ --> جميع أنواع المراجع هي في الواقع مُنشئات console.log(Number.prototype); //[Number: 0] console.log(Object.prototype);//{}
للكائن بالطريقتين التاليتين لتعيين الخصائص والأساليب المشتركة:
prototype
للمنشئgetPrototype
لطريقة الكائن (obj).وظيفة الجبهة الوطنية () { console.log("هذه هي الوظيفة"); } // استخدم بنية بناء جملة السمة لكائن الوصول console.log(fn.prototype); console.log(fn['prototype']);//fn {} // نوع الكائن يوفر طريقة getPrototypeOf() console.log(Object.getPrototypeOf(fn)); //[Function]
يتم استخدام أسلوب Object.getOwnPropertyDescriptors()
للحصول على واصفات كافة خصائص الكائن الخاصة به.
var result = Object.getOwnPropertyDescriptor(Object.prototype,'constructor'); console.log(result) // نتائج الإخراج هي كما يلي: //{ // القيمة: [الوظيفة: الكائن]، // قابل للكتابة: صحيح، // قابل للتعداد: خطأ، // شكلي: صحيح // }
constructor是在创建函数的时候自动添加的,指向构造函数本身
يمكنك تعيين خصائص وأساليب النموذج الأولي بالطريقتين التاليتين:
اسم Constructor.prototype.Attribute = قيمة السمة؛ Constructor.prototype.Method name = function(){};
عندما نحتاج إلى إضافة العديد من السمات إلى النموذج الأولي، يكون من المزعج جدًا كتابة
构造函数.prototype.属性名
مرارًا وتكرارًا، يمكننا تعديلprototype
بأكمله مباشرةً
buildor.prototype = {. اسم السمة: قيمة السمة، اسم الطريقة: function(){}}
function foo () {}foo.prototype = { المنشئ: فو، الاسم: "مربى" ، العمر: 18, العنوان: 'Beijing'}var fn = new foo()console.log(fn.address) //
سيكون لكل كائن طريقة isPrototypeOf()
، والتي تُستخدم لتحديد ما إذا كان الكائن نموذج أولي لكائن آخر.
رمز العينة كما يلي: // تحديد الكائن من خلال المُهيئ var obj = { الاسم: "مربى" } // تحديد وظيفة المنشئ Hero() {} // قم بتعيين الكائن obj إلى النموذج الأولي للمنشئ Hero Hero.prototype = obj; // إنشاء كائن من خلال المُنشئ var Hero = new Hero(); // تحدد الطريقة isPrototypeOf() ما إذا كان الكائن المحدد هو النموذج الأولي لكائن آخر var result = obj.isPrototypeOf(hero); console.log(result);// true
يتحقق من أن كائن
obj
هو النموذج الأولي للكائنhero
بعد ذلك نستخدم جزءًا من التعليمات البرمجية لتوسيع فهمنا لسلسلة النموذج الأولي:
السيناريو : ابحث عن الكائنات الموجودة في كائن obj الخطوات التي يتم إجراؤها بواسطة سمة العنوان js: 1. سيتم تشغيل عملية الحصول 2. ابحث عن السمة في الكائن الحالي 3. إذا لم يتم العثور عليها، فسيتم البحث في كائن سلسلة النموذج الأولي (__proto__) 1. سينتهي البحث إذا لم يتم العثور عليه، فسوف يستمر في البحث على طول سلسلة النموذج الأولي حتى يتم العثور على النموذج الأولي للمستوى الأعلى (ما هو النموذج الأولي للمستوى الأعلى غير واضح مؤقتًا)
var obj = {. الاسم: "مربى" ، العمر: 19 } /* المتطلبات: ابحث عن سمة العنوان في كائن obj*/ // يتم البحث في سلسلة النموذج الأولي طبقة تلو الأخرى، وإذا لم يتم العثور عليه، فسيتم البحث عنه حتى يتم العثور على النموذج الأولي ذي المستوى الأعلى obj.__proto__ = {} obj.__proto__.__proto__ = {} obj.__proto__.__proto__.__proto__ = { العنوان: "بكين" } console.log(obj.address) // بكين console.log(obj.__proto__.__proto__.__proto__) // { العنوان: "بكين" }
وأخيرا العثور على سمة العنوان
那么这里有一个问题,如果一直没有查到,会无穷尽的去查找吗?接下来我们就来了解一下
كما ذكرنا أعلاه، لن نقوم بالبحث إلى ما لا نهاية على طول سلسلة النموذج الأولي. عندما يتم العثور على النموذج الأولي ذي المستوى الأعلى، سيتم إرجاع undefined
إذا لم يتم العثور عليه بعد.
إذن ما هو النموذج الأولي عالي المستوى؟
نموذج التعليمات البرمجية كما يلي:
var obj = { name: 'jam' }console.log(obj.__proto__) // {}console.log(obj.__proto__.__proto__) //
النموذج الأولي للكائن الحرفي الفارغ obj هو:
{}
.{}
هو النموذج الأولي للمستوى الأعلى. عندما نستمر في طباعة__proto__
لأعلى، يتم إرجاع قيمة فارغة، مما يثبت أن الطبقة السابقة هي بالفعل النموذج الأولي للمستوى الأعلى.
الشكل التالي هو ملحق للنموذج الأولي للمستوى الأعلى مفقود في الجزء الأول من الكود:
顶层原型就是Object.prototype
3.1 إذن أين نهاية سلسلة النموذج الأولي؟ على سبيل المثال، هل يحتوي الكائن الثالث أيضًا على سمة النموذج الأولي __proto__
؟
var obj = {name:'jam'}obj.__proto__ = {}obj.__proto__.__proto__ = {}obj.__proto__.__proto__.__proto__ = {}console.log(obj.__proto__.__proto__.__proto__.__proto__) // {}
وجدنا أن النتيجة المطبوعة أعلاه هي空对象{}
var obj = { الاسم: "مربى" ، العمر: 19 } console.log(obj.__proto__) // {} console.log(Object.prototype) // {} console.log(obj.__proto__ === Object.prototype) //
الكائن الحقيقي هو الفئة الأصلية لجميع الفئات، لذا فإن obj.__proto__ هو في الواقع Object.prototype،
console.log(obj.__proto__ === Object.prototype) // true
يمكننا أن نرى أن النتيجة Object.prototype هي النموذج الأولي للمستوى الأعلى.
{}
3.2 ثم يمكننا أن نسأل : {}
هل هناك أي شيء مميز في النماذج الأولية؟
console.log(obj.__proto__.__proto__.__proto__.__proto__.__proto__) // null
Object.prototype
هي كائن فارغ {}، إلا أنه ليس فارغًا، لكن الخصائص الموجودة بداخله غير قابلة للإحصاء، على سبيل المثال، لنطبع constructor
خاصية لرؤية <!-- يمكن ملاحظة أن هناك سمة منشئة وليست فارغة -->console.log(Object.prototype.constructor) // [Function: Object] <!-- يشير المُنشئ إلى الكائن -->
Object.prototype
من خلال الأسلوب Object.getOwnPropertyDescriptors()
. console.log(Object.getOwnPropertyDescriptors(Object.prototype)) // كما هو موضح في لقطة الشاشة الطويلة أدناه