از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
ES6 Iterators و GeneratorsIterators و Generators معمولاً در هنگام نوشتن کد یک فکر ثانویه هستند، اما اگر بتوانید چند دقیقه در مورد روش استفاده از آنها برای ساده کردن کد خود فکر کنید، بسیاری از اشکال زدایی و پیچیدگی شما را نجات خواهند داد. با تکرار کننده ها و مولدهای جدید ES6، جاوا اسکریپت عملکردهای مشابهی را دریافت می کند …
سرفصلهای مطلب
تکرارکنندهها و مولدها معمولاً در هنگام نوشتن کد یک فکر ثانویه هستند، اما اگر بتوانید چند دقیقه به روش استفاده از آنها برای سادهسازی کد خود فکر کنید، از اشکالزدایی و پیچیدگی زیادی جلوگیری میکنند. با تکرار کننده ها و مولدهای جدید ES6، جاوا اسکریپت عملکردی مشابه Iterable جاوا دارد و به ما امکان می دهد تکرار خود را سفارشی کنیم. روی اشیاء.
به عنوان مثال، اگر یک شی Graph داشته باشید، می توانید به راحتی از یک ژنراتور برای عبور از گره ها یا لبه ها استفاده کنید. این با قرار دادن منطق پیمایش در شی Graph در جایی که به آن تعلق دارد، کد بسیار تمیزتری را ایجاد می کند. این تفکیک منطق، عمل خوبی است، و تکرارکننده ها/تولیدکنندگان، پیروی از این بهترین شیوه ها را آسان تر می کنند.
ES6 Iterators و Generators
تکرار کننده ها
با استفاده از تکرار کننده ها، می توانید راهی برای تکرار با استفاده از آن ایجاد کنید for...of
برای شی سفارشی خود بسازید. بجای استفاده از for...in
، که فقط با استفاده از تمام خصوصیات شیء تکرار می شود for...of
به ما اجازه میدهد یک تکرار سفارشیتر و ساختار یافتهتر بسازیم که در آن مقادیر را برای هر تکرار انتخاب کنیم.
در زیر کاپوت، for...of
در واقع استفاده می کند Symbol.iterator
. Recall Symbols یک ویژگی جدید در JavaScript ES6 است. این Symbol.iterator
نمادی با هدف خاص است که به ویژه برای دسترسی به تکرار کننده داخلی یک شی ساخته شده است. بنابراین، میتوانید از آن برای بازیابی تابعی استفاده کنید که روی یک شی آرایه تکرار میشود، مانند:
var nums = (6, 7, 8);
var iterator = nums(Symbol.iterator)();
iterator.next(); // Returns { value: 6, done: false }
iterator.next(); // Returns { value: 7, done: false }
iterator.next(); // Returns { value: 8, done: false }
iterator.next(); // Returns { value: undefined, done: true }
وقتی از for...of
ساختار، این در واقع همان چیزی است که در زیر استفاده می شود. توجه داشته باشید که هر مقدار بعدی چگونه برگردانده می شود، همراه با یک نشانگر که به شما می گوید آیا در اکثر موارد نیازی به استفاده ندارید next()
به صورت دستی مانند این، اما این گزینه در صورتی وجود دارد که یک مورد استفاده داشته باشید که به حلقه کردن پیچیده تری نیاز دارد.
شما می توانید استفاده کنید Symbol.iterator
برای تعریف تکرار تخصصی برای یک شی. بنابراین بیایید بگوییم که شما شیء خود را دارید که یک لفاف برای جملات است، Sentence
.
function Sentence(str) {
this._str = str;
}
برای تعریف اینکه چگونه روی قسمتهای داخلی شی جمله تکرار میکنیم، یک تابع تکرارکننده نمونه اولیه ارائه میکنیم:
Sentence.prototype(Symbol.iterator) = function() {
var re = /\S+/g;
var str = this._str;
return {
next: function() {
var match = re.exec(str);
if (match) {
return {value: match(0), done: false};
}
return {value: undefined, done: true};
}
}
};
اکنون، با استفاده از تکرارکننده ای که در بالا ایجاد کردیم (شامل یک رشته regex که فقط با کلمات مطابقت دارد)، می توانیم به راحتی کلمات هر جمله ای را که ارائه می کنیم تکرار کنیم:
var s = new Sentence('Good day, kind sir.');
for (var w of s) {
console.log(w);
}
// Prints:
// Good
// day,
// kind
// sir.
ژنراتورها
ساخت ژنراتورهای ES6 روی بالای آنچه که تکرار کننده ها با استفاده از نحو خاص برای ایجاد آسان تر تابع تکرار ارائه می کنند. ژنراتورها با استفاده از function*
کلمه کلیدی. در یک function*
، می توانید بارها و بارها با استفاده از مقادیر را برگردانید yield
. این yield
کلمه کلیدی در توابع مولد برای توقف اجرا و برگرداندن یک مقدار استفاده می شود. می توان آن را به عنوان یک نسخه مبتنی بر ژنراتور در نظر گرفت return
کلمه کلیدی. در تکرار بعدی، اجرا در آخرین نقطه از سر گرفته می شود yield
مورد استفاده قرار گرفت.
function* myGenerator() {
yield 'foo';
yield 'bar';
yield 'baz';
}
myGenerator.next(); // Returns {value: 'foo', done: false}
myGenerator.next(); // Returns {value: 'bar', done: false}
myGenerator.next(); // Returns {value: 'baz', done: false}
myGenerator.next(); // Returns {value: undefined, done: true}
یا، می توانید از آن استفاده کنید for...of
ساختن:
for (var n of myGenerator()) {
console.log(n);
}
// Prints
// foo
// bar
// baz
در این مورد، میتوانیم ببینیم که Generator پس از بازگشت، مراقبت میکند {value: val, done: bool}
شیء برای شما، که همه در زیر کاپوت به کار گرفته می شود for...of
.
بنابراین چگونه می توانیم از ژنراتورها به نفع خود استفاده کنیم؟ با بازگشت به مثال قبلی خود، میتوانیم آن را ساده کنیم Sentence
تکرار کننده به کد زیر:
Sentence.prototype(Symbol.iterator) = function*() {
var re = /\S+/g;
var str = this._str;
var match;
while (match = re.exec(str)) {
yield match(0);
}
};
توجه کنید که چگونه تابع تکرار کننده (اکنون یک ژنراتور) بسیار کوچکتر از نسخه قبلی است. ما دیگر نیازی به برگرداندن یک شی با عبارت نداریم next
تابع، و دیگر نیازی به بازگرداندن آن نداریم {value: val, done: bool}
هدف – شی. در حالی که این صرفه جویی ممکن است در این مثال حداقل به نظر برسد، اما با افزایش پیچیدگی ژنراتورهای شما، سودمندی آن به راحتی قابل درک خواهد بود.
مزایای
مانند جیک آرچیبالد اشاره می کند که برخی از مزایای این ژنراتورها عبارتند از:
-
تنبلی: مقادیر قبل از زمان محاسبه نمی شوند، بنابراین اگر تا پایان آن را تکرار نکنید، زمان را برای محاسبه مقادیر استفاده نشده تلف نخواهید کرد.
-
بی نهایت: از آنجایی که مقادیر از قبل محاسبه نمیشوند، میتوانید مجموعهای از مقادیر بینهایت را برگردانید. فقط مطمئن شوید که در یک نقطه از حلقه خارج شده اید.
-
تکرار رشته: با تشکر از
Symbol.iterator
، String اکنون تکرار کننده خاص خود را دارد تا حلقه زدن روی کاراکترها را بسیار آسان تر کند. تکرار بر روی نمادهای کاراکتر یک رشته می تواند یک درد واقعی باشد. این به ویژه در حال حاضر مفید است که جاوا اسکریپت ES5 از یونیکد پشتیبانی می کند.برای (نماد var رشته) {
console.log(symbol);
}
نتیجه
در حالی که تکرار کننده ها و مولدها ویژگی های اضافی بزرگی نیستند، اما کمک زیادی به پاکسازی کد و سازماندهی آن می کنند. حفظ منطق تکرار با شیئی که به آن تعلق دارد، تمرین خوبی است، که به نظر میرسد بیشتر تمرکز ویژگیهای ES6 باشد. به نظر می رسد این استاندارد به سمت قابلیت ساختار و طراحی دوستی جاوا حرکت می کند، در حالی که همچنان سرعت توسعه زبان های پویا را حفظ می کند.
نظر شما در مورد ویژگی های جدید ES6 چیست؟ چه نوع کاربردهای جالبی برای تکرارکننده ها و مولدها دارید؟ در نظرات به ما اطلاع دهید!
با تشکر از جیک آرچیبالد برای مقاله عالی که جزئیات بیشتر روش عملکرد تکرارکننده ها و ژنراتورها در ES6 را شرح می دهد.
(برچسبها برای ترجمه)# توضیح داده شده
منتشر شده در 1403-01-30 18:31:07