در جاوااسکریپت، یک شیء زمانی تکرارپذیر (Iterable) است که رفتار تکرارِ خود را تعریف کرده باشد؛ یعنی مشخص کند که چه مقادیری در ساختاری مثل حلقه for...of پیمایش شوند. برخی از انواع دادهایِ داخلیِ جاوااسکریپت مثل Array یا Map یک رفتار تکرارِ پیشفرض دارند، در حالی که انواع دیگر (مثل اشیای معمولی یا همان Object) این رفتار پیشفرض را ندارند.
یک شیء برای اینکه تکرارپذیر شود، باید متد [Symbol.iterator]() را پیادهسازی کند. این یعنی خود آن شیء (یا یکی از اشیای موجود در زنجیره پروتوتایپ آن) باید ویژگی یا کلیدی به نام Symbol.iterator داشته باشد.
یک شیء تکرارپذیر ممکن است قابلیت بارها پیمایش شدن را داشته باشد، یا اینکه فقط یکبار بتوان روی آن پیمایش انجام داد. این وظیفه برنامهنویس است که تفاوت این دو حالت را در کد خود بداند:
تکرارپذیرهایی که فقط یکبار قابلیت تکرار دارند (مثل ژنراتورها)، معمولاً در متد [Symbol.iterator]() خودشان، کلمه کلیدی this (یعنی ارجاع به خودشان) را برمیگردانند.
در طرف مقابل، تکرارپذیرهایی که میتوانند بارها و بارها تکرار شوند، باید در هر بار فراخوانی متد [Symbol.iterator]، یک ایتریتورِ کاملاً جدید را برگردانند.
بیا این مفهوم را در قالب یک کد آزمایشی بررسی کنیم:
function* makeIterator() {
yield 1;
yield 2;
}
const iter = makeIterator();
for (const itItem of iter) {
console.log(itItem); // خروجی: 1 و بعد 2
}
console.log(iter[Symbol.iterator]() === iter); // true
// این مثال به ما نشان میدهد که ژنراتور (ایتریتور) یک شیء تکرارپذیر است؛
// شیئی که متد [Symbol.iterator]() آن، خودِ `iter` (یعنی خودش) را برمیگرداند.
// در نتیجه، این شیء فقط و فقط «یکبار» میتواند تکرار شود.
// حالا اگر ما متد [Symbol.iterator]() این شیء را به یک تابع/ژنراتور جدید تغییر دهیم
// که یک شیء ایتریتور/ژنراتور جدید برمیگرداند، `iter` میتواند بارها تکرار شود:
iter[Symbol.iterator] = function* () {
yield 2;
yield 1;
};
شما میتوانید اشیای تکرارپذیر مخصوص به خودتان را به این صورت بسازید:
const myIterable = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
},
};
این تکرارپذیرهای سفارشی را میتوان به راحتی و مثل همیشه در حلقههای for...of یا سینتکس پخشکننده (اسپرد) استفاده کرد:
for (const value of myIterable) {
console.log(value);
}
// خروجیها به ترتیب:
// 1
// 2
// 3
[...myIterable]; // خروجی: [1, 2, 3]
انواع دادهای String، Array، TypedArray، Map و Set همگی جزو تکرارپذیرهای داخلی و پیشفرض جاوااسکریپت هستند؛ چرا که شیء پروتوتایپِ (Prototype) همهی آنها به صورت پیشفرض متد Symbol.iterator را در خود دارد.
برخی از دستورات، عبارات و ساختارها در جاوااسکریپت برای کار کردن، انتظار یک شیء تکرارپذیر (Iterable) را دارند. برای نمونه میتوان به حلقههای for...of، سینتکس اسپرد یا همان پخشکننده (...)، عبارت yield* و سینتکس مخرب یا همان ساختارشکنی (Destructuring) اشاره کرد:
// استفاده در حلقه for...of
for (const value of ["a", "b", "c"]) {
console.log(value);
}
// "a"
// "b"
// "c"
// استفاده در سینتکس اسپرد روی یک رشته (رشتهها تکرارپذیر هستند)
[..."abc"]; // ["a", "b", "c"]
// استفاده در عبارت *yield
function* gen() {
yield* ["a", "b", "c"];
}
gen().next(); // { value: "a", done: false }
// استفاده در ساختارشکنی (Destructuring) به همراه شیء Set
const [a, b, c] = new Set(["a", "b", "c"]);
console.log(a); // "a"
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://developer.mozilla.org/en-US/docs/Web/JavaScript