المكررات والمولدات في 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، فسيولّد المترجم حلقات _
لاستهداف تطبيق المكرّرات المضمَّن في المحرّك.