المكررات والمولدات في TypeScript

من موسوعة حسوب


الكائنات القابلة للتكرار (Iterables)

يُعدّ كائنٌ قابلًا للتكرار إذا كان يطبِّق الخاصيّة ‎Symbol.iterator‎. هناك بعض الأنواع القابلة للتكرار المضمّنة في اللغة مثل ‎Array‎، و‎Map‎، و‎Set‎، و‎String‎، و‎Int32Array‎، و‎Uint32Array‎، إلخ… تُطبِّق هذه الأنواع الخاصية ‎Symbol.iterator‎ داخليًّا. تكون الدالةُ ‎Symbol.iterator‎ على كائنٍ معيّنٍ الدالةَ المسؤولةَ عن إعادة قائمة القيم التي يُكرَّر عليها.

جمل ‎for..of

تدور الجملة ‎ for..of‎‎حول كائن قابل للتكرار مُستدعيَةً الخاصيّة ‎Symbol.iterator‎ الموجودة على الكائن. هذا مثال بسيط على كيفيّة استخدام ‎for..of‎ للدوران على عناصر مصفوفة:

let someArray = [1, "string", false];

for (let entry of someArray) {
    console.log(entry); // 1, "string", false
}

جمل ‎for..of‎ مقابلَ جملِ ‎for..in

تُكرِّر كل من الجملتين ‎for..of‎ و‎for..in‎ على القوائم؛ لكن القيم المكرَّر عليها مختلفة، إذ تُعيد ‎for..in‎ قائمةَ مفاتيحِ الكائن المُكرَّر عليه، أمّا ‎for..of‎ فتُعيد قائمة قيمِ الخاصيات العدديّة الخاصة بالكائن المُكرَّر عليه.

يُوضّح هذا المثال الفرق:

let list = [4, 5, 6];

for (let i in list) {
   console.log(i); // "0", "1", "2",
}

for (let i of list) {
   console.log(i); // "4", "5", "6"
}

ومن الاختلافات كذلك أنّ الجملة ‎for..in‎ تعمل على أي كائن، وتعمل كطريقة لاستكشاف خاصيات الكائن. أمّا ‎for..of‎ فتُستعمَل فقط للوصول إلى قيم الكائنات القابلة للتكرار. تطبّق الكائنات المضمّنة مثل ‎Map‎ و‎Set‎ الخاصيّةَ ‎Symbol.iterator‎، ما يسمح بالوصول إلى القيم المُخزَّنة:

let pets = new Set(["Cat", "Dog", "Hamster"]);
pets["species"] = "mammals";

for (let pet in pets) {
   console.log(pet); // "species"
}

for (let pet of pets) {
    console.log(pet); // "Cat", "Dog", "Hamster"
}

توليد الشيفرة

استهداف النسختين ES5 وES3

عند استهداف النسخة ES5 أو النسخة ES3، فيُسمح باستخدام المُكرِّرات (iterators) على قيم النوع ‎Array‎ فقط. وسيُطلَق خطأ إن استُعملت حلقات ‎for..of‎ على قيمٍ أخرى غير المصفوفات، حتى ولو طبّقت هذه القيم الخاصيّة ‎Symbol.iterator‎.

سيُولِّد المترجم حلقة ‎for‎ بسيطة لحلقات ‎for..of‎، مثلًا الشيفرةُ:

let numbers = [1, 2, 3];
for (let num of numbers) {
    console.log(num);
}

تولّد الشيفرةَ:

var numbers = [1, 2, 3];
for (var _i = 0; _i < numbers.length; _i++) {
    var num = numbers[_i];
    console.log(num);
}

استهداف النسخة ECMAScript 2015 وما بعدها

عند استهداف محرّكٍ (engine) متوافق مع ECMAScipt 2015، فسيولّد المترجم حلقات ‎_‎ لاستهداف تطبيق المكرّرات المضمَّن في المحرّك.

مصادر