for...in في JavaScript

من موسوعة حسوب
مراجعة 04:15، 17 يناير 2018 بواسطة عبد اللطيف ايمش (نقاش | مساهمات)
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)

التعبير البرمجي for...in يُنشِئ حلقة تكرار تمر على الخاصيات القابلة للإحصاء (enumerable properties) التابعة لأحد الكائنات، ويمكن تنفيذ تعابير برمجية لكل خاصية من خاصيات الكائن.

البنية العامة

for (variable in object) {
  //...
}

variable

ستُنسَد قيمة الخاصية مختلفة لهذا المتغير في كل دورة.

object

الكائن الذي سنمر على الخاصيات القابلة للإحصاء (enumerable properties) التابعة له.

الوصف

حلقة التكرار for...in تمر على الخاصيات القابلة للإحصاء (enumerable properties) فقط، فالكائنات المُنشَأة من الدوال البانية المُضمَّنة في اللغة مثل Array و Object تملك خاصيات غير قابلة للإحصاء مورثة (من الكائنين Object.prototype و String.prototype مثلًا)، مثل الدالة indexOf()‎ التابعة للكائن String أو الدالة toString()‎ التابعة للكائن Object. هذه الحلقة ستمر على جميع الخاصيات القابلة للإحصاء التابعة للكائن الحالي والكائن الذي يرثه عبر سلسلة prototype.

حلقة التكرار for...in تمر على خاصيات الكائن بترتيبٍ اعتباطي (انظر صفحة المعامل delete لمزيدٍ من المعلومات حول السبب وراء عدم القدر على الاعتماد على ترتيب عملية التكرار). إذا غُيِّرَت قيمة إحدى الخاصيات في إحدى دورات هذه الحلقة ثم تم الوصول إليها لاحقًا عبر حلقة التكرار، فستكون قيمتها ضمن حلقة التكرار تساوي قيمتها الحالية، أما الخاصية التي حُذِفَت قبل زيارتها في حلقة التكرار لن يمكن زيارتها ضمن حلقة التكرار؛ أما الخاصيات التي أُضيفَت إلى الكائن أثناء وقوع حلقة التكرار فقد يُمرّ عليها أو لا يمرّ عليها ضمن حلقة التكرار؛ لذا من الأفضل عدم إضافة أو تعديل أو حذف خاصيات الكائن أثناء حلقة التكرار ما عدا الخاصية الحالية؛ فلا توجد ضمانة أنَّ الخاصيات المُضافة حديثًا سيُمرّ عليها من حلقة التكرار، ولا أيّ قيمة للخاصيات المُعدَّلة ستُستخدَم (عدا الخاصية الحالية)، ولا إذا كانت حلقة التكرار ستمر على الخاصيات المحذوفة قبل حذفها.

المرور على المصفوفات

تُعدّ فهارس المصفوفات خاصياتٍ قابلةً للإحصاء لها أسماءٌ رقميةٌ وهي تُماثِل خاصيات الكائنات الأخرى؛ لكن لا توجد هنالك أيّة ضمانة أنَّ حلقة for...in ستُعيد الفهارس في أيّ ترتيبٍ معيّن، إذا إنَّ حلقة for...in ستُعيد جميع الخاصيات القابلة للإحصاء، بما في ذلك الخاصيات التي أسماؤها ليست رقميةً أو تلك التي ورثتها المصفوفة.

ولأنَّ ترتيب المرور على عناصر الكائن تابعٌ لطريقة تطبيق المواصفة في البرمجية (المتصفح أو غيره)، فالمرور على عناصر المصفوفة قد لا يكون بترتيبٍ معيّن، وبالتالي يكون من الأفضل استخدام حلقة التكرار for مع فهرس رقمي (أو الدالة Array.prototype.forEach()‎ أو حلقة for...of) عند المرور على عناصر المصفوفات التي يكون ترتيب الوصول إلى عناصرها مهمًا.

المرور على خاصيات الكائن دونًا عن الخاصيات الموروثة

إذا أردتَ المرور على خاصيات الكائن نفسه، لكن دون المرور على الخاصيات الموروثة من سلسلة prototype، فاستخدام الدالة getOwnPropertyNames()‎ أو تحقق من الخاصية عبر الدالة hasOwnProperty()‎ (يمكن أيضًا استخدام الدالة propertyIsEnumerable()‎).

أمثلة

الشيفرة الآتية تستخدم حلقة التكرار for...in للمرور على جميع الخاصيات القابلة للإحصاء التابعة لأحد الكائنات، وتضبط سلسلةً نصيةً تحتوي على اسم كل خاصية وقيمتها:

var obj = {a: 1, b: 2, c: 3};
    
for (const prop in obj) {
  console.log(`obj.${prop} = ${obj[prop]}`);
}

// الناتج
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"

الشيفرة الآتية توضِّح استخدام الدالة hasOwnProperty()‎ للحصول على الخاصيات التابعة لأحد الكائنات والتي لا يرثها عبر سلسلة prototype:

var triangle = {a: 1, b: 2, c: 3};

function ColoredTriangle() {
  this.color = 'red';
}

ColoredTriangle.prototype = triangle;

var obj = new ColoredTriangle();

for (const prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    console.log(`obj.${prop} = ${obj[prop]}`);
  } 
}

// الناتج
// "obj.color = red"

دعم المتصفحات

الميزة Chrome Firefox Internet Explorer Opera Safari
الدعم الأساسي نعم نعم 6 نعم نعم

مصادر ومواصفات