نحن نعلم أن JS موجه نحو الكائن. عندما يتعلق الأمر بتوجيه الكائن ، من المحتم أن تنطوي على مفهوم الفصول. بشكل عام ، تحتوي اللغات المكتوبة بقوة مثل C# و Java على بناء جملة ثابتة لتحديد الفئات. الفرق بين JS هو أنه يمكنه استخدام طرق مختلفة لتنفيذ فئاتها وكائناتها. هناك العديد من طرق التنفيذ العامة:
1. طريقة المصنع
تشير طريقة المصنع إلى إنشاء وظيفة مصنع لإرجاع نوع كائن معين.
نسخة الكود كما يلي:
وظيفة CreateCar (scolor ، idoors ، impg)
{
var otempcar = كائن جديد ؛
otempcar.color = scolor ؛
otempcar.doors = idoors ؛
otempcar.mpg = impg ؛
otempcar.showcolor = function ()
{
تنبيه (this.color) ؛
}
إرجاع otempcar ؛
}
var ocar1 = createCar ("Red" ، 4،23) ؛
var ocar2 = createCar ("Blue" ، 3،25) ؛
OCAR1.SHOWCOLOR () ؛
OCAR2.SHOWCOLOR () ؛
بهذه الطريقة ، في كل مرة تستدعي وظيفة المصنع ، سيتم إنشاء كائن جديد. ولكن المشكلة هي أنه في كل مرة يتم فيها إنشاء كائن جديد ، يجب إنشاء عرض وظيفة جديد ، مما يجعل كل كائن له نسخة خاصة به ، وفي الواقع ، تشترك جميع الكائنات في نفس الوظيفة. هل يتم تعريف طريقة الكائن خارج وظيفة المصنع ، ثم يتم إعطاء الكائن مؤشرًا للوظيفة ، على النحو التالي
نسخة الكود كما يلي:
وظيفة الرسوم ()
{
تنبيه (this.color) ؛
}
وظيفة CreateCar (scolor ، idoors ، impg)
{
var otempcar = كائن جديد ؛
otempcar.color = scolor ؛
otempcar.doors = idoors ؛
otempcar.mpg = impg ؛
otempcar.showcolor = showcolor ؛
إرجاع otempcar ؛
}
var ocar1 = createCar ("Red" ، 4،23) ؛
var ocar2 = createCar ("Blue" ، 3،25) ؛
OCAR1.SHOWCOLOR () ؛
OCAR2.SHOWCOLOR () ؛
بهذه الطريقة ، ليست هناك حاجة لإنشاء وظيفة الرسوم الخاصة بها لكل كائن ، ولكن فقط إنشاء مؤشر لهذه الوظيفة. لذلك ، يتم تقديم طريقة المنشئ.
2. طريقة المنشئ
يشبه المُنشئ وظيفة المصنع ، رمز المثال هو كما يلي:
نسخة الكود كما يلي:
وظيفة السيارة (scolor ، idoors ، impg)
{
this.color = scolor ؛
this.doors = idoors ؛
this.mpg = impg ؛
this.showcolor = function ()
{
تنبيه (this.color) ؛
}
}
var ocar1 = سيارة جديدة ("أحمر" ، 4،23) ؛
var ocar2 = سيارة جديدة ("Blue" ، 3،25) ؛
في المنشئ ، لا يوجد كائن يتم إنشاؤه داخليًا ، ولكن يتم استخدام الكلمة الرئيسية التي يتم استخدامها. عند الاتصال بالمشغل الجديد ، يتم إنشاء كائن قبل تنفيذ السطر الأول من التعليمات البرمجية. ولكن ما هي المشكلات التي ستحدث مع هذا؟ لحل هذه المشكلة ، تم تقديم طريقة النموذج الأولي التالي.
3. طريقة النموذج الأولي
تستفيد هذه الطريقة من خاصية النموذج الأولي للكائن ، والتي يمكن اعتبارها النموذج الأولي الذي يعتمد عليه كائن جديد. هنا ، استخدم المنشئ الفارغ لتعيين اسم الفصل. ثم يتم تعيين جميع الطرق والسمات مباشرة إلى سمة النموذج الأولي. على النحو التالي:
نسخة الكود كما يلي:
وظيفة السيارة ()
{}
car.prototype.color = "red" ؛
car.prototype.doors = 4 ؛
car.prototype.mpg = 23 ؛
car.prototype.drivers = صفيف جديد ("Mike" ، "Sue") ؛
car.prototype.showcolor = function ()
{
تنبيه (this.color) ؛
}
لا يمكن طريقة النموذج الأولي إلا تعيين القيم مباشرة ، ولا يمكن نقل المعلمات إلى المُنشئ قيمة تهيئة السمة. عند استخدام هذه الطريقة ، ستواجه مشكلتين. المشكلة الأولى هي أنه يجب إنشاء كل كائن قبل تغيير القيمة الافتراضية للسمة بهذه الطريقة. لا يمكن الحصول مباشرة على قيم الخصائص التي تحتاجها عند إنشاء كل كائن. هذا مزعج. المشكلة الثانية هي عندما تشير السمة إلى الكائن. لن تكون هناك مشاكل في مشاركة الوظائف ، ولكن ستكون هناك مشاكل في مشاركة الكائنات. لأن كل مثيل يحتاج عمومًا إلى تنفيذ كائنه الخاص.
على النحو التالي:
نسخة الكود كما يلي:
var ocar1 = سيارة جديدة () ؛
var ocar2 = new Car () ؛
OCAR1.DRIVIRS.PUSH ("Matt") ؛
ALERT (OCAR1.DRIVERS) ؛ // الإخراج "Mike ، Sue ، Matt"
التنبيه (OCAR2.Divers) ؛ // الإخراج "Mike ، Sue ، Matt"
لذلك فإن سمة برامج التشغيل هي مجرد مؤشر للكائن ، لذلك تشترك جميع الحالات في الواقع في نفس الكائن. نظرًا لهذه المشكلات ، نقدم طريقة استخدام المفصل التالية وطريقة النموذج الأولي.
4. طريقة مُنشأة/نموذج أولي
تتمثل فكرة هذه الطريقة في استخدام مُنشئ لتحديد جميع الخصائص غير الوظيفية للكائن (بما في ذلك الخصائص العادية والسمات التي تشير إلى الكائن) ، واستخدام نموذج أولي لتحديد خصائص الوظيفة (الطرق) للكائن. والنتيجة هي أنه يتم إنشاء جميع الوظائف مرة واحدة فقط ، وأن كل كائن له مثيل سمة الكائن الخاص به. رمز العينة كما يلي:
نسخة الكود كما يلي:
وظيفة السيارة (scolor ، idoors ، impg)
{
this.color = scolor ؛
this.doors = idoors ؛
this.mpg = impg ؛
this.drivers = صفيف جديد ("Mike" ، "Sue") ؛
}
car.prototype.showcolor = function ()
{
تنبيه (this.color) ؛
}
var ocar1 = سيارة جديدة ("أحمر" ، 4،23) ؛
var ocar2 = سيارة جديدة ("Blue" ، 3،25) ؛
OCAR1.DRIVIRS.PUSH ("Matt") ؛
تنبيه (OCAR1.DRIVERS) ؛ // الإخراج "مايك ، سو ، مات"
التنبيه (OCAR2.DRIVES) ؛ // الإخراج "Mike ، Sue"
كما يتضح من رمز المثال ، تحل هذه الطريقة مشكلتين في الطريقة السابقة في نفس الوقت. ومع ذلك ، وبهذه الطريقة ، لا يزال بعض المطورين يشعرون أنه ليس مثاليًا.
5. طريقة النموذج الأولي الديناميكي
يمكننا أن نرى أن معظم اللغات الموجهة للكائنات تغلف بصريًا الخصائص والأساليب. ومع ذلك ، يتم تعريف طريقة العرض في الطريقة أعلاه خارج الفصل. لذلك ، قاموا بتصميم نهج النموذج الأولي الديناميكي. الفكرة الأساسية لهذا النهج هي نفس نهج المُنشئ/النموذج الأولي المختلط ، والفرق الوحيد هو موقع طريقة الكائن. كما هو موضح أدناه:
نسخة الكود كما يلي:
وظيفة السيارة (scolor ، idoors ، impg)
{
this.color = scolor ؛
this.doors = idoors ؛
this.mpg = impg ؛
this.drivers = صفيف جديد ("Mike" ، "Sue") ؛
إذا (typeof car._initialized == "غير محدد")
{
car.prototype.showcolor = function ()
{
تنبيه (this.color) ؛
}
}
car._initialized = true ؛
}
وبهذه الطريقة ، يتم إنشاء car.prototype.showcolor مرة واحدة فقط. هذا التبعية تجعل هذا الرمز يشبه تعريف الفئة بلغات أخرى.
6. طريقة المصنع المختلط
عادة ما يكون هذا النهج بمثابة حل لا يمكن استخدامه كنهج سابق. الغرض منه هو إنشاء مُنشئ مزيف يعيد فقط مثيلات جديدة لكائن آخر.
نسخة الكود كما يلي:
وظيفة CreateCar ()
{
var otempcar = كائن جديد ؛
otempcar.color = "red" ؛
otempcar.doors = 4 ؛
otempcar.mpg = 23 ؛
otempcar.showcolor = function ()
{
تنبيه (this.color) ؛
} ؛
إرجاع otempcar ؛
}
var car = new Car () ؛
نظرًا لأن المشغل الجديد يتم استدعاؤه داخل مُنشئ Car () ، يتم تجاهل المشغل الثاني الجديد تلقائيًا. يتم تمرير الكائنات التي تم إنشاؤها داخل المنشئ إلى المتغير VAR. يحتوي هذا النهج على نفس المشكلات مثل النهج الكلاسيكي من حيث الإدارة الداخلية لطرق الكائن. لذلك ، يوصى بشدة: تجنب استخدام هذه الطريقة ما لم يكن ضروريًا للغاية.