المتغيرات والوظائف الخاصة
إذا لم يتم توفير المتغيرات والوظائف المحددة داخل الوظيفة خارجيًا ، فلا يمكن الوصول إليها خارجيًا ، أي أن المتغيرات الخاصة ووظائف الوظيفة.
نسخة الكود كما يلي:
<script type = "text/javaScript">
اختبار الوظيفة () {
var color = "Blue" ؛ // Private Variable
var fn = function () // وظيفة خاصة
{
}
}
</script>
وبهذه الطريقة ، لا يمكن الوصول إلى لون المتغيرات و FN خارج اختبار كائن الوظيفة ، وتصبح خاصة:
نسخة الكود كما يلي:
var obj = new test () ؛
تنبيه (obj.color) ؛ // غير محدد منبثقة
تنبيه (obj.fn) ؛ // نفسه على النحو الوارد أعلاه
المتغيرات والوظائف الثابتة
عندما يتم تعريف وظيفة ما ، لا تزال السمات والوظائف التي تمت إضافتها إليها يمكن الوصول إليها من خلال الكائن نفسه ، ولكن لا يمكن الوصول إلى أمثلةها. وتسمى هذه المتغيرات والوظائف المتغيرات الثابتة والوظائف الثابتة على التوالي.
نسخة الكود كما يلي:
<script type = "text/javaScript">
وظيفة OBJ () {
}
obj.num = 72 ؛ // متغير ثابت
obj.fn = function () // وظيفة ثابتة
{
}
تنبيه (obj.num) ؛ // 72
تنبيه (typeof obj.fn) // وظيفة
var t = new obj () ؛
تنبيه (T.Name) ؛ // غير محدد
تنبيه (typeof t.fn) ؛ // غير محدد
</script>
متغيرات ووظائف مثيل
في البرمجة الموجهة للكائنات ، بالإضافة إلى بعض وظائف المكتبة ، ما زلنا نأمل في تحديد بعض الخصائص والأساليب في نفس الوقت الذي يمكن فيه الوصول إلى الكائن ، والذي يمكن الوصول إليه بعد التثبيت. يمكن لـ JavaScript القيام بذلك أيضًا
نسخة الكود كما يلي:
<script type = "text/javaScript">
وظيفة OBJ () {
this.a = [] ؛ // متغير مثيل
this.fn = function () {// method method
}
}
console.log (typeof obj.a) ؛ // غير محدد
console.log (typeof obj.fn) ؛ // غير محدد
var o = new obj () ؛
console.log (typeof oa) ؛ //هدف
console.log (typeof o.fn) ؛ //وظيفة
</script>
أضف طرقًا وخصائصًا جديدة إلى متغيرات وطرق المثيل
نسخة الكود كما يلي:
<script type = "text/javaScript">
وظيفة OBJ () {
this.a = [] ؛ // متغير مثيل
this.fn = function () {// method method
}
}
var o1 = new obj () ؛
O1.A.Push (1) ؛
o1.fn = {} ؛
console.log (O1.A) ؛ // [1]
console.log (typeof o1.fn) ؛ //هدف
var o2 = new obj () ؛
console.log (O2.a) ؛ // []
console.log (typeof o2.fn) ؛ //وظيفة
</script>
يتم تعديل A و FN في O1 ، ولكن ليس في O2. نظرًا لأن المصفوفات والوظائف هي كائنات وهي أنواع مرجعية ، فهذا يعني أنه على الرغم من أن الخصائص والأساليب في O1 هي نفس تلك الموجودة في O2 ، إلا أنها ليست مرجعًا ، بل نسخة من الخصائص والأساليب المحددة بواسطة كائن OBJ.
لا يوجد أي مشكلة في الخصائص ، ولكنها مشكلة كبيرة للطرق ، لأن الأساليب تقوم بنفس الوظيفة تمامًا ، ولكن هناك نسختان. إذا كان كائن الوظيفة يحتوي على آلاف وطرق مثيل ، فيجب أن يحافظ كل مثيل منه على نسخة من الآلاف من الطرق. من الواضح أن هذا غير علمي. ماذا يمكنني أن أفعل؟ جاء النموذج الأولي.
المفاهيم الأساسية
كل وظيفة نقوم بإنشائها لها خاصية النموذج الأولي ، وهي مؤشر لكائن ، والغرض منه هو احتواء خصائص وطرق يمكن مشاركتها بواسطة جميع الحالات من نوع معين. بعد ذلك ، النموذج الأولي هو كائن النموذج الأولي لمثيل الكائن الذي تم إنشاؤه عن طريق استدعاء المُنشئ.
ميزة استخدام النموذج الأولي هي أنه يسمح لمثيل الكائن بمشاركة الخصائص والطرق التي يحتوي عليها. أي بدلاً من إضافة معلومات كائن التعريف إلى المنشئ ، يمكنك إضافة هذه المعلومات مباشرة إلى النموذج الأولي. المشكلة الرئيسية في استخدام المنشئات هي أنه يجب إنشاء كل طريقة مرة واحدة في كل مثيل.
في JavaScript ، هناك نوعان من القيم والقيم الأصلية وقيم الكائن. يحتوي كل كائن على نموذج أولي خاصية داخلية ، والذي نسميه عادةً نموذجًا أوليًا. يمكن أن تكون قيمة النموذج الأولي كائنًا أو فارغًا. إذا كانت قيمتها كائنًا ، فيجب أن يكون للكائن أيضًا النموذج الأولي الخاص به. هذا يشكل سلسلة خطية ، والتي نسميها سلسلة النموذج الأولي.
معنى
يمكن استخدام الوظائف كمشاركات. بالإضافة إلى ذلك ، لا تحتوي الوظيفة إلا على سمة نموذج أولي ويمكن الوصول إليها ، لكن مثيل الكائن لا يحتوي على هذه السمة ، لا يوجد سوى سمة __proto__ الداخلية. __proto__ هو رابط غامض في الكائن إلى النموذج الأولي ذي الصلة. وفقًا للمعيار ، لا يتم الكشف عن __proto__ للجمهور ، مما يعني أنها خاصية خاصة ، لكن محرك Firefox كشفه وأصبح خاصية مشتركة ، يمكننا الوصول إليها وضبطها.
نسخة الكود كما يلي:
<script type = "text/javaScript">
var browser = function () {} ؛
browser.prototype.run = function () {
ALERT ("أنا جيكو ، نواة من Firefox") ؛
}
var bro = browser () ؛
bro.run () ؛
</script>
عندما نسمي طريقة Broun.run () ، نظرًا لعدم وجود مثل هذه الطريقة في Bro ، فسوف يبحث عنها في __proto__ ، أي المتصفح. النموذج ، لذلك يتم تنفيذ طريقة Run () أخيرًا. (هنا ، تمثل الحرف الكسمات للوظيفة المُنشئ لتمييز الوظائف العادية)
عند استدعاء المُنشئ لإنشاء مثيل ، سيحتوي المثيل على مؤشر داخلي (__proto__) يشير إلى النموذج الأولي للمنشئ. هذا الاتصال موجود بين المثيل والنموذج الأولي للمنشئ ، وليس بين المثيل والمشارك.
نسخة الكود كما يلي:
<script type = "text/javaScript">
وظيفة الشخص (الاسم) {
this.name = name ؛
}
person.prototype.printname = function () {
تنبيه (this.name) ؛
}
var person1 = شخص جديد ('Byron') ؛
var person2 = شخص جديد ('Frank') ؛
</script>
يحتوي مثيل الشخص على سمة الاسم ، ويقوم تلقائيًا بإنشاء سمة __proto__ ، والتي تشير إلى النموذج الأولي للشخص ، ويمكنك الوصول إلى طريقة اسم الطباعة المحددة في النموذج الأولي ، والتي ربما تشبه هذا:
كستناء آخر:
نسخة الكود كما يلي:
<script type = "text/javaScript">
وظيفة الحيوان (الاسم) // تراكم المنشئ
{
this.name = name ؛ // تعيين خصائص الكائن
}
animal.prototype.behavior = function () // إضافة طريقة السلوك إلى النموذج الأولي لمؤسسة الفئة الأساسية
{
تنبيه ("هذا هو"+this.name) ؛
}
var dog = حيوان جديد ("كلب") ؛ // إنشاء كائن الكلب
var cat = حيوان جديد ("Cat") ؛ // إنشاء كائن Cat
dog.behavior () ؛ // استدعاء طريقة السلوك مباشرة من خلال كائن الكلب
Cat.Behavior () ؛ // الإخراج "هذه قطة"
التنبيه (الكلب.
</script>
يمكن ملاحظة من البرنامج الذي يقوم بتشغيل النتائج التي يمكن استدعاء الأساليب المحددة على النموذج الأولي للمُنشئ مباشرة من خلال الكائن ، ويتم مشاركة الكود. (يمكنك محاولة إزالة خاصية النموذج الأولي في Animal.Prototype.Behavior لمعرفة ما إذا كان لا يزال بإمكانه التشغيل.) هنا ، تشير خاصية النموذج الأولي إلى الكائن الحي.
مثيل كائن الصفيف
دعونا نلقي نظرة على مثيل كائن الصفيف. عندما نقوم بإنشاء مجموعة الكائنات 1 ، يكون نموذج الكائن الفعلي لـ Array1 في محرك JavaScript كما يلي:
نسخة الكود كما يلي:
var array1 = [1،2،3] ؛
يحتوي كائن Array1 على قيمة سمة طول 3 ، ولكن يمكننا إضافة عناصر إلى Array1 بالطريقة التالية:
Array1.push (4) ؛
تأتي طريقة الدفع من طريقة تشير إلى الكائن بواسطة عضو __proto__ في Array1 (Array.Prototye.push ()). ويرجع ذلك بالتحديد لأن جميع كائنات الصفيف (التي تم إنشاؤها من خلال []) تحتوي على عضو __proto__ يشير إلى نفس كائن الطريقة مع الدفع ، عكس ، إلخ (Array.Prototype) ، أن كائنات الصفيف هذه يمكنها استخدام Push ، عكسي وطرق أخرى.
مثيل كائن الوظيفة
نسخة الكود كما يلي:
دالة قاعدة () {
this.id = "base"
}
نسخة الكود كما يلي:
var obj = new base () ؛
ما هي نتيجة هذا الرمز؟ نموذج الكائن الذي نراه في محرك JavaScript هو:
ماذا فعل المشغل الجديد بالضبط؟ في الواقع ، كان الأمر بسيطًا للغاية ، لقد فعل ثلاثة أشياء.
نسخة الكود كما يلي:
var obj = {} ؛
obj .__ proto__ = base.prototype ؛
base.call (obj) ؛
سلسلة النموذج الأولي
سلسلة النموذج الأولي: عندما يتم استرداد خاصية أو طريقة من كائن ، إذا لم يكن للكائن نفسه الخاصية أو الطريقة ، فسيبحث عن كائن النموذج الأولي الذي تربطه. إذا لم يكن هناك نموذج أولي ، فسيبحث عن سلف النموذج الأولي المرتبط بالنموذج الأولي. إذا لم يكن هناك المزيد ، فاستمر في البحث عن الكائن المشار إليه بواسطة النموذج الأولي. النموذج ، وما إلى ذلك حتى يكون النموذج الأولي ....... غير محدد (النموذج الأولي للكائن غير محدد) ، وبالتالي تشكيل ما يسمى "سلسلة النموذج الأولي".
نسخة الكود كما يلي:
<script type = "text/javaScript">
شكل وظيفة () {
this.name = "الشكل" ؛
this.toString = function () {
إرجاع هذا.
}
}
وظيفة twoshape () {
this.name = "2 الشكل" ؛
}
وظيفة المثلث (الجانب ، الارتفاع) {
this.name = "triangle" ؛
this.side = الجانب ؛
this.height = الارتفاع ؛
this.getarea = function () {
إرجاع this.side*this.height/2 ؛
}
}
twoshape.prototype = new mape () ؛
Triangle.prototype = جديد twoshape () ؛
</script>
هنا ، يتم إنشاء كيان جديد باستخدام شكل مُنشئ () ، ثم يتم استخدامه للكتابة فوق النموذج الأولي للكائن.
نسخة الكود كما يلي:
<script type = "text/javaScript">
شكل وظيفة () {
this.name = "الشكل" ؛
this.toString = function () {
إرجاع هذا.
}
}
وظيفة twoshape () {
this.name = "2 الشكل" ؛
}
وظيفة المثلث (الجانب ، الارتفاع) {
this.name = "triangle" ؛
this.side = الجانب ؛
this.height = الارتفاع ؛
this.getarea = function () {
إرجاع this.side*this.height/2 ؛
}
}
twoshape.prototype = new mape () ؛
Triangle.prototype = جديد twoshape () ؛
twoshape.prototype.constructor = twoshape ؛
Triangle.prototype.constructor = مثلث ؛
var my = مثلث جديد (5،10) ؛
my.getarea () ؛
my.tostring () ؛ // مثلث
my.constructor ؛ // مثلث (الجانب ، الارتفاع)
</script>
النموذج الأولي الميراث
ميراث النموذج الأولي: في نهاية سلسلة النموذج الأولي ، هو كائن النموذج الأولي الذي أشار إليه سمة النموذج الأولي لمؤسسة الكائن. كائن النموذج الأولي هذا هو سلف جميع الأشياء ، ونفذ هذا الجد الأساليب التي يجب أن يكون لجميع الأشياء مثل tostring بشكل فطري. المُنشئون المدمجون الآخرون ، مثل الوظيفة ، والطراز ، والسلسلة ، والتاريخ ، و regexp ، ورثوا من هذا الجد ، لكن كل منهم يحدد سماتهم وطرقهم ، بحيث يُظهر أحفادهم خصائص العشائر الخاصة بكل منها.
في ECMascript ، يتم تحقيق طريقة تنفيذ الميراث من خلال الاعتماد على سلسلة النموذج الأولي.
نسخة الكود كما يلي:
<script type = "text/javaScript">
مربع الوظيفة () {// تسمى الوظيفة الموروثة supertype (فئة الوالدين ، الفئة الأساسية)
this.name = "jack" ؛
}
تسمى الوظائف الوظيفية () {// الوظائف الموروثة الأنواع الفرعية (الفئات الفرعية ، فئات مشتقة)
this.age = 300 ؛
}
// وراثة من خلال سلسلة النموذج الأولي ، قم بتعيين سمات النموذج الأولي للنوع الفرعي
// New Box () سيسلم المعلومات الموجودة في المربع والمعلومات الموجودة في النموذج الأولي إلى Tree
tree.prototype = new box () ؛ // tree ورث الصندوق وتشكل سلسلة من خلال النموذج الأولي.
شجرة var = شجرة جديدة () ؛
ALERT (TREE.NAME) ؛ // POPT JACK
</script>
مشكلة في سلسلة النموذج الأولي: على الرغم من أن سلسلة النماذج الأولية قوية للغاية ويمكن استخدامها لتنفيذ الميراث ، فإنها لديها أيضًا بعض المشكلات. المشكلة الأكثر أهمية تأتي من النموذج الأولي الذي يحتوي على نوع المرجع. تتم مشاركة سمات النموذج الأولي الذي يحتوي على أنواع مرجعية بواسطة جميع الحالات ؛ هذا هو السبب في تعريف السمات في البنائين ، وليس في كائنات النموذج الأولي. عندما يتم تحقيق الميراث من خلال نموذج أولي ، يصبح النموذج الأولي في الواقع مثيلًا لنوع آخر. لذلك ، تصبح سمة المثيل الأصلي سمة النموذج الأولي.
عند إنشاء مثيل من نوع فرعي ، لا يمكن نقل الوسيطة إلى مُنشئ SuperType. في الواقع ، ينبغي القول أنه لا توجد طريقة لتمرير المعلمات إلى مُنشئ SuperType دون التأثير على جميع مثيلات الكائنات. بالإضافة إلى المشكلة التي تمت مناقشتها للتو بسبب إدراج قيم النوع المرجعي في النماذج الأولية ، من النادر استخدام سلاسل النموذج الأولي وحدها في الممارسة العملية.
كستناء آخر:
نسخة الكود كما يلي:
<script type = "text/javaScript">
وظيفة الشخص (الاسم)
{
this.name = name ؛ // تعيين خصائص الكائن
} ؛
person.prototype.company = "Microsoft" ؛ // قم بتعيين خصائص النموذج الأولي
person.prototype.sayhello = وظيفة () // طريقة النموذج الأولي
{
ALERT ("مرحبًا ، أنا"+ this.name+ "من"+ this.company) ؛
} ؛
var billgates = شخص جديد ("billgates") ؛ // إنشاء كائن شخص
Billgates.Sayhello () ؛ // يرث محتوى النموذج الأولي والمخرجات "مرحبًا ، أنا بُشرطة من Microsoft"
var Jobs = شخص جديد ("الوظائف") ؛
Jobs.company = "Apple" ؛ // قم بتعيين سمة شركتك الخاصة للتستر على سمة شركة النموذج الأولي
Jobs.sayhello = function ()
{
ALERT ("HI ،" + this.name + "like" + this.company) ؛
} ؛
الوظائف.
Billgates.Sayhello () ؛ // لا تؤثر تغطية الوظائف على النموذج الأولي ، لا تزال الفواتير تخرج
</script>
انظر المثال التالي لسلسلة النموذج الأولي:
نسخة الكود كما يلي:
<script type = "text/javaScript">
وظيفة السنة () {
this.value = 21 ؛
}
year.prototype = {
الطريقة: الدالة () {
}
} ؛
وظيفة مرحبا () {
} ؛
// تعيين خاصية النموذج الأولي لـ HI إلى كائن مثيل السنة
hi.prototype = new Year () ؛
hi.prototype.year = 'hello world' ؛
hi.prototype.constructor = مرحبًا ؛
var test = new hi () ؛ // قم بإنشاء مثيل جديد لـ HI
// سلسلة النموذج الأولي
اختبار [مرحبا مثال]
HI.Prototype [مثال على العام]
{السنة: 'hello world'}
السنة. النموذج
{طريقة:…}؛
Object.prototype
{toString: ...} ؛
</script>
من المثال أعلاه ، يتم توريث كائن الاختبار من النمط hi.prototype و year.prototype ؛ لذلك يمكن أن يصل إلى طريقة طريقة النموذج الأولي للعام ، وفي الوقت نفسه يمكنه الوصول إلى قيمة خاصية المثيل
__ptoto__ السمة
سمة __ptoto__ (غير مدعومة من قبل متصفح IE) هي مؤشر لكائن النموذج الأولي للمثال. تتمثل وظيفتها في الإشارة إلى مُنشئ سمة النموذج الأولي للمُنشئ. من خلال هاتين السمة ، يمكنك الوصول إلى الخصائص والأساليب في النموذج الأولي.
يتكون مثيل الكائن في JavaScript بشكل أساسي من سلسلة من الخصائص. من بين هذه الخصائص ، هناك خاصية خاصة غير مرئية داخليًا - __proto__. تشير قيمة هذه الخاصية إلى النموذج الأولي لمثيل الكائن. مثيل الكائن يحتوي فقط على نموذج أولي فريد.
نسخة الكود كما يلي:
<script type = "text/javaScript">
مربع الوظيفة () {// agritice ، يمثل المنشئ
box.prototype.name = "trigkit4" ؛ // ettributes
box.prototype.age = "21" ؛
box.prototype.run = وظيفة () // النموذج الأولي
{
إرجاع this.name + this.age + 'studying' ؛
}
}
var box1 = new box () ؛
var box2 = new box () ؛
التنبيه (box1.constructor) ؛ // إنشاء السمة ، يمكنك الحصول على المُنشئ نفسه ،
// يتم وضع الوظيفة بواسطة مؤشر النموذج الأولي ثم الحصول على المُنشئ نفسه
</script>
الفرق بين سمة __proto__ وسمة النموذج الأولي
النموذج الأولي هو خاصية ملكية في كائن الوظيفة.
__proto__ هي خاصية ضمنية لكائن عادي. عندما يكون جديدًا ، سيشير إلى الكائن الذي يشير إليه النموذج الأولي ؛
__ptoto__ هي في الواقع سمة لكائن كيان معين ، في حين أن النموذج الأولي هو سمة تنتمي إلى المنشئ. لا يمكن استخدام __ptoto__ إلا في بيئات التعلم أو تصحيح الأخطاء.
عملية تنفيذ وضع النموذج الأولي
1. ابحث أولاً عن السمات أو الأساليب في مثيل المنشئ ، وإذا كان الأمر كذلك ، فأعود على الفور.
2. إذا لم يكن هناك مثيل للمُنشئ ، فانتقل إلى كائن النموذج الأولي والعودة على الفور.
كائن النموذج الأولي
نسخة الكود كما يلي:
<script type = "text/javaScript">
مربع الوظيفة () {// agritice ، يمثل المنشئ
box.prototype.name = "trigkit4" ؛ // ettributes
box.prototype.age = "21" ؛
box.prototype.run = وظيفة () // النموذج الأولي
{
إرجاع this.name + this.age + 'studying' ؛
}
}
var box1 = new box () ؛
التنبيه (box1.name) ؛ // trigkit4 ، القيمة في النموذج الأولي
box1.name = "Lee" ؛
تنبيه (box1.name) ؛ // لي ، انتقل إلى المبدأ
var box2 = new box () ؛
التنبيه (box2.name) ؛ // trigkit4 ، قيمة النموذج الأولي ، لم يتم تعديله بواسطة box1
</script>
المنشئ
نسخة الكود كما يلي:
<script type = "text/javaScript">
مربع الوظيفة () {
this.name = "Bill" ؛
}
box.prototype.name = "trigkit4" ؛ // ettributes
box.prototype.age = "21" ؛
box.prototype.run = وظيفة () // النموذج الأولي
{
إرجاع this.name + this.age + 'studying' ؛
}
var box1 = new box () ؛
ALERT (box1.name) ؛ // BILL ، القيمة في النموذج الأولي
box1.name = "Lee" ؛
تنبيه (box1.name) ؛ // لي ، انتقل إلى المبدأ
</script>