1. كائن النمط
1.1 سلبيات من البنائين
تقوم JavaScript بإنشاء كائنات جديدة من خلال المُنشئين ، بحيث يمكن اعتبار المُنشئين كقوالب للكائنات. يمكن تعريف خصائص وطرق كائن المثيل داخل المنشئ.
دالة القط (الاسم ، اللون) {this.name = name ؛ this.color = color ؛} var cat1 = new cat ('Big Hair' ، 'White') ؛ cat1.name // 'big hair'cat1.color //' White 'وظيفة CAT في الكود أعلاه هي مُنشئ. يتم تعريف سمة الاسم وسمة اللون داخليًا. جميع كائنات المثيل سوف تولد هاتين السمة. ومع ذلك ، فإن القيام بذلك هو مضيعة لموارد النظام ، لأنه لا يمكن مشاركة الخصائص بين مثيلات الكائن في نفس المنشئ.
دالة القط (الاسم ، اللون) {this.name = name ؛ this.color = اللون ؛ this.meow = function () {console.log ('mew ، mew ، mew ...') ؛ سترفي الكود أعلاه ، CAT1 و CAT2 هما مثيلان لنفس المنشئ. ومع ذلك ، تختلف أساليب المواء الخاصة بهم ، أي في كل مرة يتم إنشاء مثيل جديد ، سيتم إنشاء طريقة مواء جديدة. هذا ليس ضروريًا ولا يهدف إلى موارد النظام ، لأن جميع أساليب المواء هي نفس السلوك ويجب مشاركتها تمامًا.
1.2 دور سمة النموذج الأولي
في لغة JavaScript ، يحتوي كل كائن على كائن النموذج الأولي المقابل ، يسمى كائن النموذج الأولي. يمكن ورث جميع الخصائص والأساليب المحددة على كائن النموذج الأولي بواسطة الكائن المشتق. هذا هو التصميم الأساسي لآلية الميراث JavaScript.
بالإضافة إلى هذا النهج ، يوفر JavaScript أيضًا طريقة أخرى لتحديد كائنات المثيل. نحن نعلم أن المُنشئ هو وظيفة وكائن ، وله أيضًا خصائصه وطرقه الخاصة. تشير سمة النموذج الأولي إلى كائن آخر ، والذي يسمى بشكل عام كائن النموذج الأولي. هذا الكائن مميز جدا. طالما أن الخصائص والأساليب المحددة عليها يمكن مشاركتها بواسطة جميع كائنات المثيل. وهذا يعني أنه عندما يقوم المُنشئ بإنشاء كائن مثيل ، يتم تعيين سمة النموذج الأولي تلقائيًا إلى كائن المثيل.
وظيفة animal (name) {this.name = name ؛} animal.prototype.color = "white" ؛ var cat1 = new Animal ('big hair') ؛ var cat2 = new animal ('erimao') ؛ cat1.color // 'white'cat2.color //' white 'يضيف الرمز أعلاه سمة لون إلى كائن النموذج الأولي لحيوان المنشئ. نتيجة لذلك ، يحمل كل من كائنات المثيل CAT1 و CAT2 هذه الخاصية.
بشكل خاص ، طالما تم تعديل كائن النموذج الأولي ، سيتم انعكاس التغييرات على الفور في كائن المثيل.
Animal.Prototype.Color = "Yellow" ؛ Cat1.Color // 'Yellow'cat2.Color //' Yellow '
يغير الرمز أعلاه قيمة سمة اللون لكائن النموذج الأولي إلى اللون الأصفر ، وستتغير قيمة سمة اللون لكائن مثيلين على الفور. وذلك لأن كائن المثيل ليس له في الواقع سمة لون ، وكلهم يقرؤون سمة اللون لكائن النموذج الأولي. وهذا يعني أنه عندما لا يحتوي كائن المثيل نفسه على خاصية أو طريقة معينة ، فسوف ينتقل إلى كائن النموذج الأولي الخاص بالمقدم للعثور على الخاصية أو الطريقة. هذا هو الشيء الخاص عن كائنات النموذج الأولي.
إذا كان كائن المثيل نفسه يحتوي على خاصية أو طريقة معينة ، فلن يبحث عن هذه الخاصية أو الطريقة في كائن النموذج الأولي.
cat1.color = 'black' ؛ cat2.color // 'Yellow'animal.prototype.color // "Yellow" ؛
يغير الرمز أعلاه خاصية اللون لكائن مثيل CAT1 إلى الأسود ، بحيث لم يعد يحتاج إلى قراءة خاصية اللون من كائن النموذج الأولي ، ولا تزال قيمة الأخير صفراء.
باختصار ، تتمثل وظيفة كائن النموذج الأولي في تحديد الخصائص والأساليب المشتركة بواسطة جميع كائنات المثيل ، لذلك يطلق عليها أيضًا النموذج الأولي لكائن المثيل ، ويمكن اعتبار كائن المثيل مشتقًا من كائن النموذج الأولي.
animal.prototype.walk = function () {console.log (this.name + 'هو المشي.') ؛} ؛يحدد الكود أعلاه طريقة المشي على كائن النمط الخاص بالحيوان ، والتي سيتم استدعاؤها على جميع كائنات مثيل الحيوانات.
1.3 سلسلة النموذج الأولي
نظرًا لأن جميع الكائنات في JavaScript لها منشآت ، وجميع المُنشئين لديهم سمات نموذجية (في الواقع جميع الوظائف لها سمات النموذج الأولي) ، فإن جميع الكائنات لها كائنات النموذج الأولي الخاص بها.
لذلك ، يمكن تعريف خصائص وطرق الكائن على نفسه أو على كائن النموذج الأولي (مثل طريقة المشي في الكود أعلاه). نظرًا لأن النموذج الأولي نفسه هو كائن وله نموذج أولي خاص به ، يتم تشكيل سلسلة النموذج الأولي. على سبيل المثال ، الكائن A هو النموذج الأولي للكائن B ، والكائن B هو النموذج الأولي للكائن C ، وهلم جرا. نظرًا لأن تتبع جذر المصدر ، يتم إنشاء الكائنات الموجودة في المصدر من مُنشئ الكائن (باستخدام الأمر الجديد ()) ، لذلك إذا قمت بتتبع الطبقة حسب الطبقة ، فيمكن في النهاية تتبع النموذج الأولي لجميع الكائنات إلى Object.prototype. إذن ، هل هناك نموذج أولي لـ Object.prototype؟ يمكن أن تكون الإجابة بنعم أو لا ، لأن النموذج الأولي للكائن. النمط النمط هو فارغة بدون أي خصائص وطرق.
Object.getPrototypeof (Object.prototype) // null
يشير الرمز أعلاه إلى أن النموذج الأولي لكائن كائن. نظرًا لأن NULL ليس له خصائص ، فإن سلسلة النموذج الأولي تنتهي هنا.
وظيفة "سلسلة النموذج الأولي" هي أنه عند قراءة سمة معينة لكائن ما ، يبحث محرك JavaScript أولاً عن سمات الكائن نفسه. إذا كان لا يمكن العثور عليه ، فسيبحث عن النموذج الأولي. إذا كان لا يمكن العثور عليها ، فسيبحث عن النموذج الأولي للنموذج الأولي. وهلم جرا ، إذا كان الكائن.
على سبيل المثال ، إذا كانت سمة النموذج الأولي للوظيفة ما تشير إلى صفيف ، فهذا يعني أنه يمكن استخدام الوظيفة كمشارك صفيف ، لأن كائنات المثيل التي تنشئها يمكنها استدعاء طريقة الصفيف من خلال سمة النموذج الأولي.
وظيفة myArray () {} myarray.prototype = new array () ؛ myarray.prototype.constructor = myarray ؛ var mine = new myarray () ؛ mine.push (1 ، 2 ، 3) ؛ mine.length // 3mine array // true trueالمنجم في الرمز أعلاه هو كائن مثيل من myarray. نظرًا لأن خاصية النموذج الأولي لـ MyArray تشير إلى صفيف ، يمكن لي استدعاء أساليب الصفيف (يتم تعريف هذه الطرق فعليًا على كائن النموذج الأولي للمصفوفة). بالنسبة إلى السطر الأخير من تعبير مثيل ، فإننا نعلم أن مشغل مثيل OF يستخدم لمقارنة ما إذا كان الكائن هو مثيل لمؤسس ، ويشير السطر الأخير إلى أن الألغام مثال على الصفيف.
مثيل الألغام من Array // يعادل (Array === MyArray.prototype.constructor) || (Array === Array.Protype.Constructor) || (Array === Object.prototype.constructor)
يوضح الرمز أعلاه جوهر عامل التشغيل ، والذي يتم مقارنته بسمات المنشئ لجميع كائنات النموذج الأولي لكائن المثيل (لإدخال هذه السمة ، يرجى الاطلاع على القسم التالي). طالما كان هناك واحد ، فسوف يعود بشكل صحيح ، وإلا فإنه سيعود خطأ.
1.4 سمة مُنشئ
يحتوي كائن النموذج الأولي على سمة مُنشأة تشير إلى وظيفة المنشئ حيث يوجد كائن النموذج الأولي افتراضيًا.
الدالة p () {} p.prototype.constructor === p // trueنظرًا لأن سمة المنشئ محددة على كائن النموذج الأولي ، فهذا يعني أنه يمكن موروثه بواسطة جميع كائنات المثيل.
الدالة p () {} var p = new p () ؛ p.constructor // function p () {} p.constructor === P.Prototype.constructor // truep.hasownproperty ('constructor') // falseيشير الرمز أعلاه إلى أن p هو كائن مثيل للمركبة P ، ولكن P نفسه ليس لديه سمة مُنشأة ، والتي تقرأ بالفعل سمة p.prototype.constructor على سلسلة النموذج الأولي.
تتمثل وظيفة سمة المنشئ في التمييز بين المُنشئ الذي يتم تعريف كائن النموذج الأولي على.
الدالة f () {} ؛ var f = new f () ؛ f.constructor ==== f // truef.constructor === regexp // falseيعني الرمز أعلاه أن استخدام خاصية المنشئ ، يتم تحديد أن وظيفة مُنشئ المتغير F هي f ، وليس regexp.
2.Object.getPrototypeOF طريقة
تُرجع Complet.GetPrototypeOF طريقة النموذج الأولي للكائن.
. من f هو f.prototypevar f = new f () ؛ object.getPrototypeof (f) === f.prototype // true
3.Object.create طريقة
يتم استخدام طريقة كائن. إنشاء كائن جديد ويمكن استبدال الأمر الجديد. إنه يقبل كائنًا كوسيطة ويُرجع كائنًا جديدًا ، والذي يرث تمامًا خصائص الأولى ، أي أن الأول يصبح النموذج الأولي للأخير.
var o1 = {p: 1} ؛ var o2 = object.create (o1) ؛ o2.p // 1في الكود أعلاه ، تنشئ طريقة كائن. إنشاء O2 استنادًا إلى O1. في هذا الوقت ، يصبح O1 النموذج الأولي لـ O2 ، أي O2 يرث جميع خصائص O1.
طريقة كائن. إنشاء ما يعادل بشكل أساسي الرمز التالي. إذا كان المتصفح القديم لا يدعم طريقة الكائن.
if (typeof object.create! == "function") {object.create = function (o) {function f () {} f.prototype = o ؛ إرجاع جديد f () ؛ } ؛}يوضح الكود أعلاه أن طريقة إنشاء COBSE.SENTER تنشئ بشكل أساسي مُنشئًا جديدًا F ، ثم يتيح سمة النموذج الأولي لـ F إلى نقطة إلى الكائن O كنموذج أولي ، وأخيراً لإرجاع مثيل F ، بحيث يمكن للمثيل أن يرث سمات O.
الكائنات الجديدة التي تم إنشاؤها بالطرق الثلاث التالية متكافئة.
var o1 = object.create ({}) ؛ var o2 = object.create (object.prototype) ؛ var o3 = new Object () ؛إذا كنت ترغب في إنشاء كائن لا يرث أي خصائص (مثل طرق ToString و ValueOF) ، فيمكنك تعيين الكائن.
var o = object.create (null) ؛ o.valueof () // typeerror: object [object] ليس له طريقة "valueof"
يشير الرمز أعلاه إلى أنه إذا كان النموذج الأولي للكائن O فارغًا ، فلا يحتوي على بعض الخصائص المحددة على كائن الكائن.
عند استخدام طريقة الكائن.
object.create () // typeerror: قد يكون النموذج الأولي للكائن كائنًا أو خاليًا فقط
الكائن الجديد الذي تم إنشاؤه بواسطة الكائن. إن إضافة أو تعديل أي طريقة على النموذج الأولي سوف تنعكس على الفور على الكائن الجديد.
var o1 = {p: 1} ؛ var o2 = object.create (o1) ؛ o1.p = 2 ؛ o2.p // 2يشير الكود أعلاه إلى أن تعديل النموذج الأولي للكائن سيؤثر على الكائن الذي تم إنشاؤه حديثًا.
بالإضافة إلى النموذج الأولي للكائن ، يمكن أن تقبل طريقة كائن. ستتم إضافة خصائص الكائن التي يصفها إلى الكائن الجديد.
var o = object.create (object.prototype ، {p1: {value: 123 ، enumeries: true} ، p2: {value: "abc" ، enumeries: true}}) ؛ o.p1 // 123o.p2 // "ABC"نظرًا لأن طريقة كائن. في هذا الوقت ، يمكنك استخدام طريقة iSprototypeof التالية لتفسير الكائن النموذج الأولي.
4.isprototypeof طريقة
يتم استخدام طريقة isprototypeof لتحديد ما إذا كان الكائن نموذجًا أوليًا لكائن آخر.
var o1 = {} ؛ var o2 = object.create (o1) ؛ var o3 = object.create (o2) ؛ o2.isprototypeof (o3) // trueo1.isprototypeof (o3) // trueيوضح الرمز أعلاه أن ISPROTYOF يعيد صحيحًا طالما أن الكائن موجود على سلسلة النموذج الأولي.
5. مثال بسيط
var classDemo = function () {// static private far var private_static_var = 'aaaa' ؛ // Static Private Method var private_static_func = function (key) {return key + private_static_var ؛ } // method private ، المفتاح هو تمرير هذا var private_func = function (self ، key) {return private_static_func (key + self.id) ؛ } var _class = function (id) {// constructor this.id = id ؛ // المتغير العام} // public method_class.prototype.public_func = function (key) {return private_func (this ، key) ؛ } return _class ؛} () ؛ var a = new classDemo ('Hello World') ؛ Alert (A.Public_func ('World Hello')) ؛لا توجد طريقة بسيطة لتنفيذ المتغيرات الخاصة والمتغيرات/الأساليب الثابتة العامة ، ولكن التغليف يكفي للقيام بذلك إلى هذا الحد.