عند إنشاء كائنات من خلال منشئي الكائنات أو الكائنات الحرفية ، عند إنشاء العديد من الكائنات مع نفس الواجهة ، سيتم إنشاء كمية كبيرة من التعليمات البرمجية المكررة. من أجل البساطة ، تم تقديم نموذج المصنع.
نموذج المصنع
وظيفة CreatePerson (الاسم ، العمر ، الوظيفة) {var obj = new Object () ؛ obj.name = الاسم ؛ obj.age = العمر ؛ obj.job = Job ؛ obj.sayhello () {Alert (this.name) ؛ } ؛ return obj ؛} var p1 = createperson ("xxyh" ، 19 ، "programmer") ؛ var p2 = createPerson ("Zhangsan" ، 18 ، "student") ؛تعمل طريقة إنشاء الكائنات على تبسيط الكود هذه بشكل كبير ، ولكن هناك أيضًا عيب ، أي نوع الكائن لا يمكن تحديده. لحل هذه المشكلة ، يظهر النمط التالي.
وضع المنشئ
قم بإنشاء مُنشئ مخصص لتحديد الخصائص وطرق أنواع الكائنات المخصصة.
وظيفة الشخص (الاسم ، العمر ، الوظيفة) {this.name = name ؛ this.age = العمر ؛ this.job = Job ؛ this.sayname = function () {Alert (this.name) ؛ } ؛} var p1 = شخص جديد ("xxyh" ، 19 ، "مبرمج") ؛ var p2 = شخص جديد ("جاك" ، 18 ، "طالب") ؛في المثال أعلاه ، يحل الشخص () محل CreatePerson (). بالإضافة إلى ذلك ، هناك العديد من الاختلافات:
• إنشاء كائنات بدون عرض ؛
• تعيين السمات والأساليب مباشرة لهذا الكائن
• لا بيان العودة
لإنشاء كائن شخص ، يجب عليك استخدام المشغل الجديد. ينقسم إلى 4 خطوات:
• إنشاء كائن جديد
• تعيين نطاق المُنشئ إلى كائن جديد
• قم بتنفيذ الرمز في المُنشئ
• إرجاع كائن جديد
P1 و P2 على التوالي حفظ مثيل الشخص.
تنبيه (p1.constructor == شخص) ؛ // truealert (p2.constructor == person) ؛ // حقيقي
من الأفضل استخدام مثيل exatef عند اكتشاف الأنواع:
تنبيه (كائن مثيل P1) ؛ // truealert (p1 مثيل الشخص) ؛ // truealert (p2 مثيل كائن) ؛ // truealert (p2 مثيل الشخص) ؛ // truealert (p2 مثيل الشخص) ؛ // حقيقي
P1 و P2 هي حالات كائن ، لأن جميع الكائنات ورثت من الكائن.
2.1 علاج المنشئين كوظائف
// استخدم var person = شخص جديد ("xxyh" ، 19 ، "مبرمج") ؛ person.sayname () ؛ // "xxyh" // استخدم كشخص وظيفة عادي ("Zhangsan" ، 18 ، "الطالب") ؛ // إضافة إلى windowwindow.sayname () ؛ // "Zhangsan" // استدعاء var obj في نطاق كائن آخر obj = new Object () ؛ person.call (OBJ ، "Jack" ، 29 ، "Manager") ؛ obj.sayname () ؛ // "Jack" ، OBJ لديه كل الخصائص والأساليب2.2 مشكلة المنشئ
تكمن مشكلة استخدام البنائين في أن كل طريقة تحتاج إلى إعادة إنشاء في كل مثيل. يحتوي كل من P1 و P2 على طريقة SayName () ، لكنهما ليسا مثيلًا للوظيفة. في JavaScript ، الوظيفة هي كائن ، لذلك في كل مرة يتم تحديد وظيفة ، يتم إنشاء كائن.
يمكن أيضًا تعريف المنشئ على هذا النحو:
وظيفة الشخص (الاسم ، العمر ، الوظيفة) {this.name = name ؛ this.age = العمر ؛ this.job = Job ؛ هذا.لذلك ، فإن وظائف تحمل نفس الاسم في حالات مختلفة ليست متساوية:
تنبيه (p1.SayName == p2.SayName) ؛ // خطأ شنيع
ومع ذلك ، فإن إنشاء وظيفتين مع نفس الوظيفة لا لزوم لها ، وليس هناك حاجة لربط الوظيفة بكائن معين قبل تنفيذ الرمز.
وظيفة الشخص (الاسم ، العمر ، الوظيفة) {this.name = name ؛ this.age = العمر ؛ this.job = Job ؛ this.sayname = sayname ؛} وظيفة sayname () {Alert (this.name) ؛} var p1 = new شخص ("xxyh" ، 19 ، "مبرمج") ؛ var p2 = شخص جديد ("Jack" ، 18 ، "الطالب") ؛ينقل ما ورد أعلاه تعريف sayname () خارج المُنشئ ، ثم يضع السمة sayname كدالة sayname العالمية داخل المنشئ. وبهذه الطريقة ، يحتوي SayName على مؤشر للوظيفة ، و P1 و P2 يشتركان في نفس وظيفة SayName () المحددة في النطاق العالمي.
ومع ذلك ، هناك مشكلة جديدة في هذا: لا يمكن استدعاء الوظائف المحددة في النطاق العالمي إلا من قبل كائن معين. وإذا حدد الكائن العديد من الطرق ، فإن النوع المرجعي يفقد تغليفه.
وضع سلسلة النموذج الأولي
كل وظيفة لها خاصية نموذجية ، وهي مؤشر يشير إلى كائن. الغرض من هذا الكائن هو تضمين الخصائص والأساليب التي يمكن مشاركتها بواسطة جميع حالات نوع معين . النموذج الأولي هو كائن النموذج الأولي لمثيل الكائن الذي تم إنشاؤه عن طريق استدعاء المُنشئ. تتمثل ميزة استخدام كائن النموذج الأولي في أن جميع مثيلات الكائنات يمكنها مشاركة الخصائص والأساليب التي تحتوي عليها. هذا يعني أنه بدلاً من تحديد معلومات مثيل الكائن في المنشئ ، تتم إضافة هذه المعلومات إلى كائن النموذج الأولي.
وظيفة person () {} person.prototype.name = "xxyh" ؛ person.prototype.age = 19 ؛ person.prototype.job = "programmer" ؛ person.prototype.sayname = function () {Alert (this.name) ؛ person1.sayname () ؛ // "xxyh" var person2 = new person () ؛ person2.sayname () ؛ // "xxyh" ALERT (person1.SayName == person2.SayName) ؛ // حقيقي3.1 فهم كائنات النموذج الأولي
فقط إنشاء وظيفة جديدة ، سيتم إنشاء خاصية النموذج الأولي للوظيفة ، والتي تشير إلى كائن النموذج الأولي للوظيفة. بشكل افتراضي ، ستحصل جميع كائنات النموذج الأولي تلقائيًا على خاصية مُنشئ. تحتوي هذه الخاصية على مؤشر إلى الوظيفة التي توجد بها خاصية النموذج الأولي. person.prototype.constructor يشير إلى الشخص.
عندما يتم استدعاء المُنشئ لإنشاء مثيل ، سيحتوي داخل المثيل على مؤشر (خاصية داخلية) إلى كائن النموذج الأولي الخاص بالمقدم ، يسمى [[النموذج الأولي]]. تم الوصول إليها عبر _proto في Firefox و Safari و Chrome. هذا الاتصال موجود بين المثيل وكائن النموذج الأولي للمُنشئ ، وليس بين المثيل والمشارك.
يوضح الشكل التالي العلاقة بين كل كائن:
person.prototype يشير إلى كائن النموذج الأولي ، و person.prototype.constructor يشير إلى الشخص. بالإضافة إلى سمة المنشئ ، هناك سمات أخرى مضافة في النموذج الأولي. تحتوي جميع مثيلات الشخص على خاصية داخلية تشير فقط إلى الشخص. النمط المحدد ، وليس لديهم علاقة مباشرة مع المنشئ.
على الرغم من أنه لا يمكن الوصول إلى [[النموذج الأولي]] ، يمكن استخدام طريقة ISProtypeOF () لتحديد ما إذا كانت هناك مثل هذه العلاقة بين الكائنات.
التنبيه (person.prototype.isprototypeof (person1)) ؛ // truealert (person.prototype.isprototypeof (person2)) ؛ // حقيقي
عند قراءة خصائص الكائن ، يتم إجراء بحث ، بهدف السمة مع الاسم المحدد. يبدأ البحث بمثيل الكائن نفسه. يبدأ البحث من مثيل الكائن نفسه. إذا تم العثور على سمة تحمل الاسم المحدد في المثيل ، يتم إرجاع قيمة السمة ؛ إذا لم يتم العثور عليها ، فاستمر في البحث عن كائن النموذج الأولي الذي أشار إليه المؤشر وابحث عن السمة مع الاسم المحدد في كائن النموذج الأولي. إذا تم العثور على هذه الخاصية في كائن النموذج الأولي ، يتم إرجاع قيمة الخاصية.
يمكن الوصول إلى القيم المحفوظة في النموذج الأولي من خلال مثيل الكائن ، ولكن لا يمكن إعادة كتابة القيم المخزنة في النموذج الأولي من خلال مثيل الكائن . إذا قمت بإضافة سمة إلى المثيل بنفس الاسم كسممة في النموذج الأولي للمثلة ، فستمنع السمة السمة في النموذج الأولي.
وظيفة person () {} person.prototype.name = "xxyh" ؛ person.prototype.age = "20" ؛ person.prototype.job = "programmer" ؛ person.prototype.sayname = function () {alert (this.name) ؛ "ooOO" ؛ تنبيه (person1.name) ؛ // "ooooo" ALERT (person2.name) ؛ // "xxyh"في المثال أعلاه ، سمة الاسم في Person1 تمنع سمة الاسم في النموذج الأولي.
عند إضافة سمة إلى مثيل كائن ، ستقوم هذه السمة بمنع السمات التي تحمل نفس الاسم المحفوظة في كائن النموذج الأولي. هذا يعني أن وجود هذه الخاصية سيمنع الوصول إلى تلك الخاصية في النموذج الأولي. استخدم حذف خصائص مثيل.
وظيفة person () {} person.prototype.name = "xxyh" ؛ person.prototype.age = "20" ؛ person.prototype.job = "programmer" ؛ person.prototype.sayname = function () {alert (this.name) ؛ "ooOO" ؛ تنبيه (person1.name) ؛ // "ooooo" ALERT (person2.name) ؛ // "xxyh" defere1.name ؛ Alert (person1.name) ؛ // "xxyh"يمكن لـ HasownProperty () اكتشاف ما إذا كانت خاصية موجودة في حالة أو في نموذج أولي.
وظيفة person () {} person.prototype.name = "xxyh" ؛ person.prototype.age = "20" ؛ person.prototype.job = "programmer" ؛ person.prototype.sayname = function () {Alert (this.name) ؛ person () ؛ Alert (person1.hasownproperty ("name")) ؛ // falseperson1.name = "ooooo" ؛ Alert (person1.hasownproperty ("name")) ؛ // حقيقييوضح الشكل التالي العلاقة بين التنفيذ والنموذج الأولي في مواقف مختلفة:
3.2 النموذج الأولي وفي المشغل
كيفية استخدام المشغل في: استخدمه بمفرده ، في حلقة من أجل. عند استخدامه بمفرده ، يعيد المشغل في صحيح عند الوصول إلى خاصية معينة من خلال الكائن ، سواء كانت موجودة في المثيل أو في النموذج الأولي.
وظيفة person () {} person.prototype.name = "xxyh" ؛ person.prototype.age = "20" ؛ person.prototype.job = "programmer" ؛ person.prototype.sayname = function () {ALERT (this.name) ؛ // trueperson1.name = "ooOO" ؛ Alert ("name" in person1) ؛ // حقيقيإلى جانب ميزة HasownProperty () السابقة ، يمكن تحديد أن خاصية هي خاصية في النموذج الأولي أو خاصية في المثيل. إذا عاد المشغل في True و HasOwnproperty يعيد خطأ ، فإن الخاصية هي خاصية في النموذج الأولي.
دالة hasprototypeproperty (كائن ، اسم) {return! object.hasownproperty (name) && (name in Object) ؛}بعد ذلك ، دعونا نلقي نظرة على استخدام HasPrototypeProperty ():
وظيفة person () {} person.prototype.name = "xxyh" ؛ person.prototype.age = "20" ؛ person.prototype.job = "programmer" ؛ person.prototype.sayname = function () {alert (this.name) ؛ // trueperson.name = "ooooo" ؛ Alert (hasprototypeproperty (الشخص ، "الاسم")) ؛ // خطأ شنيععند استخدام حلقة FO-in ، جميع الخصائص التي يمكن الوصول إليها من خلال الكائن ، بما في ذلك الخصائص في المثيل والخصائص في النموذج الأولي. سيتم أيضًا إرجاع سمات المثيل التي تمنع البيانات غير المقدرة في النموذج الأولي (أي السمات التي تم تمييزها على أنها خاطئة بواسطة [[التعداد]]) ، لأنه وفقًا للوائح ، تكون جميع السمات المحددة من قبل المطورين قابلة للتعداد.
للحصول على جميع خصائص مثيل التعداد على كائن ، يمكنك استخدام طريقة الكائن.
وظيفة person () {} person.prototype.name = "xxyh" ؛ person.prototype.age = "20" ؛ person.prototype.job = "programmer" ؛ person.prototype.sayname = function () {Alert (this.name) ؛ // الاسم ، العمر ، الوظيفة ، saynamevar p1 = شخص جديد () ؛ p1.name = "ooooo" ؛ p1.age = 15 ؛ var p1_keys = object.keys (p1) ؛ ALERT (p1_keys) ؛ // الاسم ، العمرإذا كنت بحاجة إلى الحصول على جميع خصائص المثيل ، فيمكنك استخدام Object.GetOwnPropertyNames ()
var keys = object.getownPropertyNames (person.prototype) ؛ Alert (Keys) ؛ // "مُنشئ ، الاسم ، العمر ، الوظيفة ، sayname"
3.3 بناء جملة النموذج الأولي أبسط
لتبسيط الإدخال ، تجاوز كائن النموذج الأولي المتكامل مع كائن حرفي يحتوي على جميع الخصائص والأساليب.
وظيفة person () {} person.prototype = {name: "xxyh" ، العمر: 18 ، المهمة: "البرمجة" ، sayname: function () {Alert (this.name) ؛ }} ؛يعين أعلاه الشخص. النمط المحدد على مساواة كائن جديد تم إنشاؤه في شكل كائن حرفي. والنتيجة هي نفسها ، لكن سمة المنشئ لم تعد تشير إلى الشخص.
يمكن إرجاع النتيجة الصحيحة من خلال مثيل ، ولكن لا يمكن للمُنشئ تحديد نوع الكائن:
var boy = new person () ؛ ALERT (boy electionof object) ؛ // truealert (boy election of person) ؛ // truealert (boy.constructor == person) ؛ // falsealert (boy.constructor == object) ؛ // حقيقي
يمكن تعيين قيمة المنشئ بالطرق التالية:
وظيفة person () {} person.prototype = {constructor: الشخص ، الاسم: "xxyh" ، العمر: 18 ، الوظيفة: "البرامج" ، sayname: function () {Alert (this.name) ؛ }} ؛3.4 ديناميات سلاسل النموذج الأولي
نظرًا لأن عملية العثور على القيم في نموذج أولي هي بحث ، فإن أي تعديلات تم إجراؤها على كائن النموذج الأولي تنعكس على المثيل. ولكن إذا تم إعادة كتابة كائن النموذج الأولي بأكمله ، فستكون النتيجة مختلفة. عند استدعاء المُنشئ ، تتم إضافة مؤشر [[النموذج الأولي]] إلى النموذج الأولي الأصلي إلى المثيل ، وتعديل النموذج الأولي إلى كائن آخر يعادل قطع الاتصال بين المنشئ والنموذج الأولي الأصلي. يشير المؤشر في المثيل إلى النموذج الأولي فقط ، وليس إلى المنشئ.
وظيفة person () {} var boy = new person () ؛ person.prototype = {constructor: الشخص ، الاسم: "xxyh" ، العمر: 29 ، الوظيفة: "مبرمج" ، sayname: function () {Alert (this.name) ؛ }} ؛ boy.sayname () ؛ // خطأالعملية المحددة هي كما يلي:
كما يتضح من أعلاه ، فإن إعادة كتابة كائنات النموذج الأولي تقطع العلاقة بين النماذج الأولية الموجودة وأي مثيلات كائنات موجودة مسبقًا ؛ أنها تشير إلى النموذج الأولي الأصلي.
3.5 النموذج الأولي للكائن الأصلي
تحدد جميع الأنواع المرجعية الأصلية طرقًا على النموذج الأولي للمُنشئ. من خلال النموذج الأولي للكائن الأصلي ، لا يمكن الحصول على الطريقة الافتراضية فقط ، ولكن يمكن أيضًا تحديد طريقة جديدة.
string.prototype.startswith = function (text) {return this.indexof (text) == 0 ؛} ؛ var msg = "Good Morning" ؛ Alert (msg.startswith ("good") ؛ // حقيقي3.6 مشاكل مع كائنات النموذج الأولي
هناك مشكلتان في نمط النموذج الأولي:
• كل شيء نفس قيمة السمة افتراضيًا.
• يتم مشاركة جميع السمات في النموذج الأولي بواسطة المثيل
لنرى مثالًا أدناه:
وظيفة person () {} person.prototype = {مُنشئ: الشخص ، الاسم: "xxyh" ، العمر: 18 ، الوظيفة: "البرامج" ، الأصدقاء: ["Zhang San" ، "li si"] ، sayname: function () {Alert (this.name) ؛ }} ؛ var p1 = new person () ؛ var p2 = new person () ؛ p1.friends.push ("wang wu") ؛ ALERT (p1.friends) ؛ // Zhang San ، Li Si ، Wang Wu Alert (p2.friends) ؛ // Zhang San ، Li Si ، Wang Wu Alert (p1.friends == p2.friends) ؛ // حقيقيتمت إضافة عنصر أعلاه من خلال p1.friends. نظرًا لأن مجموعة الأصدقاء موجودة شخصيًا ومع ذلك ، فإن الحالات عمومًا لها جميع سماتها الخاصة.
استخدم وضع المنشئ ووضع النموذج الأولي مجتمعًا
يتم استخدام وضع المنشئ لتحديد خصائص المثيل ، ويتم استخدام وضع النموذج الأولي لتحديد الأساليب والخصائص المشتركة. وبهذه الطريقة ، سيكون لكل مثيل نسخته الخاصة من سمات المثيل ، ولكن في الوقت نفسه ، شارك إشارة إلى الطريقة.
وظيفة الشخص (الاسم ، العمر ، الوظيفة) {this.name = name ؛ this.age = العمر ؛ this.job = Job ؛ this.friends = ["Zhang San" ، "li si"] ؛ }} var p1 = شخص جديد ("Xiao Xiao Yihan" ، 18 ، "مبرمج") ؛ var p2 = شخص جديد ("kuiba" ، 10 ، "Monster Hunt") ؛ p1.friends.push ("wang wu") ؛ ALERT (p1.friends) ؛ // Zhang San ، Li Si ، Wang Wu's Alert (p2.friends) ؛ // Zhang San ، Li Si Alert (p1.friends == p2.friends) ؛ // falsealsealert (p1.sayname == p2.SayName) ؛ // حقيقيفي المثال أعلاه ، يتم تعريف خصائص المثيل في المنشئ ، في حين يتم تعريف مُنشئ الخصائص المشتركة وطريقة sayname () في النموذج الأولي. لن يؤثر تعديل p1.friends على نتائج p2.friends.
وضع النموذج الأولي الديناميكي
يلف نمط النموذج الأولي الديناميكي جميع المعلومات في المُنشئ ، ومن خلال تهيئة النموذج الأولي في المنشئ ، فإنه يحافظ على ميزة استخدام كل من المنشئ والنموذج الأولي. وهذا يعني أنه من الممكن تحديد ما إذا كان يجب تهيئة النموذج الأولي عن طريق التحقق مما إذا كانت الطريقة التي يجب أن تكون موجودة.
وظيفة الشخص (الاسم ، العمر ، الوظيفة) {// property this.name = name ؛ this.age = العمر ؛ this.job = Job ؛ // method if (typeof this.sayname! = "function") {person.prototype.sayname = function () {Alert (this.name) ؛ }}}سيتم إضافة هذا فقط إلى النموذج الأولي عندما لا تكون طريقة SayName () موجودة ، وسيتم تنفيذها فقط عندما يتم استدعاء المنشئ لأول مرة.
نمط مُنشئ الطفيليات
تتمثل فكرة هذا النمط في إنشاء وظيفة تتمثل وظيفتها في تغليف الكود الذي ينشئ الكائن ثم إرجاع الكائن الذي تم إنشاؤه حديثًا.
وظيفة الشخص (الاسم ، العمر) {var obj = new Object () ؛ obj.name = الاسم ؛ obj.age = العمر ؛ obj.sayname = function () {Alert (this.name) ؛ } return obj ؛} var boy = new شخص ("xxyh" ، 19 ، "مبرمج") ؛ boy.sayname () ؛تجدر الإشارة إلى: أولاً وقبل كل شيء ، ليس للكائن الذي تم إرجاعه أي علاقة مع المُنشئ أو سمات النموذج الأولي للمُنشئ ؛ لا يختلف الكائن الذي تم إرجاعه بواسطة المُنشئ عن الكائن الذي تم إنشاؤه خارج المنشئ. لا يمكن الاعتماد على مشغل مثيل OF لتحديد نوع الكائن.
نمط مُنشئ مستقر
يشير كائن آمن إلى كائن ليس له سمات عامة ولا تشير أساليبه إلى ذلك. يتبع المنشئون المستقرون نمطًا مشابهًا للمصمم الطفيلي ، ولكن هناك اختلافان:
• لا تشير طريقة مثيل الكائن الذي تم إنشاؤه حديثًا إلى هذا ؛
• لا يسمى المنشئ باستخدام المشغل الجديد
أعد كتابة مُنشئ الشخص على النحو التالي:
وظيفة الشخص (الاسم ، العمر ، الوظيفة) {var obj = new Object () ؛ obj.sayname = function () {Alert (name) ؛ } ؛ إرجاع OBJ ؛} وظيفة الشخص (الاسم ، العمر ، الوظيفة) {var obj = new Object () ؛ obj.sayname = function () {Alert (name) ؛ } ؛ إرجاع OBJ ؛}تتحدث المقالة أعلاه لفترة وجيزة عن إنشاء كائنات JavaScript هي كل المحتوى الذي أشاركه معك. آمل أن يعطيك مرجعًا وآمل أن تتمكن من دعم wulin.com أكثر.