در زبان جاوااسکریپت، یک ایتریتور (Iterator) شیئی است که یک توالی (Sequence) از مقادیر و احتمالاً یک مقدار بازگشتی در زمان پایان یافتن آن توالی را تعریف میکند.
به طور دقیقتر، هر شیئی که پروتکل ایتریتور (Iterator protocol) را پیادهسازی کند، یک ایتریتور محسوب میشود. برای این کار، این شیء باید یک متد به نام next() داشته باشد؛ متدی که در هر بار صدا زدن، شیئی را با دو ویژگی (Property) زیر برمیگرداند:
value: مقدار بعدی در توالی تکرار.
done: یک مقدار بولین (اصطلاحاً پرچم) است؛ اگر تمام مقادیر توالی قبلاً مصرف شده باشند، مقدار آن true میشود. اگر در کنار done: true مقداری در value وجود داشته باشد، همان مقدار بازگشتیِ نهاییِ ایتریتور خواهد بود.
یک شیء ایتریتور پس از ساخته شدن، میتواند با صدا زدن مکرر متد next() به صورت صریح پیمایش شود. به فرآیند حرکت روی یک ایتریتور، «مصرف کردن ایتریتور» (Consuming the iterator) میگویند؛ چرا که این کار عموماً فقط یکبار قابل انجام است. پس از اینکه مقدار نهایی تولید شد، صدا زدنهای بعدی متد next() باید کماکان شیء { done: true } را برگردانند.
رایجترین ایتریتور در جاوااسکریپت، ایتریتورِ آرایه (Array iterator) است که هر یک از مقادیر آرایه مرتبط با خود را به ترتیب و پشت سر هم برمیگرداند.
شاید پیش خودتان تصور کنید که تمام ایتریتورها را میتوان به شکل آرایه هم نشان داد، اما اینطور نیست! آرایهها باید به طور کامل و یکجا در حافظه تخصیص داده شوند (فضا بگیرند)، اما ایتریتورها مقادیر را فقط در زمان نیاز (درست موقع صدا زدن next) مصرف میکنند. به همین دلیل، ایتریتورها میتوانند توالیهایی با اندازه نامحدود را نشان دهند؛ مثلاً بازه تمام اعداد صحیح بین 0 تا مثبت بینهایت (Infinity)!
بیا با هم یک مثال واقعی را ببینیم که دقیقاً همین کار را انجام میدهد. این کد امکان ساخت یک ایتریتورِ بازه (Range Iterator) را فراهم میکند؛ ابزاری که توالی از اعداد صحیح را از نقطه شروع (start - شامل خود عدد) تا نقطه پایان (end - بدون شامل شدن خود عدد) و با گامهای مشخص (step) تعریف میکند. مقدار بازگشتی نهایی آن، تعداد دفعاتی است که تکرار انجام شده و این آمار توسط متغیر iterationCount ردیابی میشود:
function makeRangeIterator(start = 0, end = Infinity, step = 1) {
let nextIndex = start;
let iterationCount = 0;
const rangeIterator = {
next() {
let result;
if (nextIndex < end) {
result = { value: nextIndex, done: false };
nextIndex += step;
iterationCount++;
return result;
}
return { value: iterationCount, done: true };
},
};
return rangeIterator;
}
حالا نحوه استفاده از این ایتریتور به شکل زیر خواهد بود:
// ساخت یک ایتریتور از ۱ تا ۱۰ با گامهای ۲ تایی
const iter = makeRangeIterator(1, 10, 2);
let result = iter.next();
while (!result.done) {
console.log(result.value); // خروجی به ترتیب: 1 3 5 7 9
result = iter.next();
}
// چاپ مقدار نهایی بعد از اتمام حلقه:
console.log("Iterated over sequence of size:", result.value);
// خروجی: 5 (چون ۵ عدد برگردانده شد که بازه بین ۰ تا ۱۰ را پوشش دادند)
📌 یک نکته مهم: در جاوااسکریپت به صورت انعکاسی (Reflectively) و مستقیم نمیتوان تشخیص داد که آیا یک شیء خاص، یک ایتریتور هست یا خیر. اگر نیاز دارید این موضوع را بررسی کنید، باید از مفهوم «تکرارپذیرها» (Iterables) استفاده کنید.
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://developer.mozilla.org/en-US/docs/Web/JavaScript