Iterator ба Generator
for...of давталтаар массивын элемент бүрийг дараалан авч болдгийг та мэднэ. Гэхдээ энэ яаж ажилладгийг бодож үзсэн үү? Ард нь iterator гэсэн механизм байдаг. Iterator ба Generator нь өөрийн дараалал бүтээх, том өгөгдлийг хэсэгчлэн боловсруулах хүчирхэг хэрэгслүүд юм.
Iterator гэж юу вэ?
Iterator бол next() гэсэн методтой объект юм. next() дуудах бүрт { value, done } хэлбэрийн объект буцаана — done нь true болтол дараалал үргэлжилнэ.
function тоолуур_үүсгэх(эхлэл, төгсгөл) {
let одоо = эхлэл;
return {
next() {
if (одоо <= төгсгөл) {
return { value: одоо++, done: false };
}
return { value: undefined, done: true };
},
};
}
const тоолуур = тоолуур_үүсгэх(1, 3);
console.log(тоолуур.next()); // { value: 1, done: false }
console.log(тоолуур.next()); // { value: 2, done: false }
console.log(тоолуур.next()); // { value: 3, done: false }
console.log(тоолуур.next()); // { value: undefined, done: true }
for...of давталт нь үнэндээ дотроо яг ийм next() дуудаж ажилладаг.
Generator функц
Generator нь iterator-г илүү хялбараар бичих арга юм. function* тэмдэглэгээг ашиглана. yield түлхүүр үг нь "одоо энэ утгыг өг, дараа нь энд зогс" гэсэн утгатай — функц зогссон газраасаа үргэлжлэн ажиллаж чадна.
function* тоо_гаргах() {
yield 1;
yield 2;
yield 3;
}
const gen = тоо_гаргах();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
// for...of-тэй хамт ашиглах нь хамгийн хялбар
for (const тоо of тоо_гаргах()) {
console.log(тоо); // 1, 2, 3
}
Generator-ын бодит хэрэглээ
Generator нь дуусашгүй дараалал үүсгэхэд маш тохиромжтой — бүх утгыг санах ойд нэг дор хадгалахгүйгээр хэрэгтэй үедээ л дараагийн утгыг үүсгэнэ.
function* fibonacci() {
let [а, б] = [0, 1];
while (true) {
// дуусашгүй дараалал
yield а;
[а, б] = [б, а + б];
}
}
const fib = fibonacci();
// зөвхөн хэрэгтэй хэдэн утгыг л авна
for (let i = 0; i < 8; i++) {
process.stdout.write(fib.next().value + " ");
}
// 0 1 1 2 3 5 8 13
// Хуудаслалт (pagination) жишээ
function* хуудас_гаргах(өгөгдөл, хэмжээ) {
for (let i = 0; i < өгөгдөл.length; i += хэмжээ) {
yield өгөгдөл.slice(i, i + хэмжээ);
}
}
const жагсаалт = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const хуудас = хуудас_гаргах(жагсаалт, 3);
console.log(хуудас.next().value); // [1, 2, 3]
console.log(хуудас.next().value); // [4, 5, 6]
console.log(хуудас.next().value); // [7, 8, 9]
console.log(хуудас.next().value); // [10]
Iterator ба Generator-ыг ойлгосноор for...of, spread operator, Array.from() зэрэг олон хэрэгсэл яаж ажилладгийг гүнзгий ойлгох болно. Эхэндээ ойлгоход хэцүү мэт санагдавч туршиж үзсэн тусам тодорхой болно — тэвчээртэй байгаарай!
Дараагийн хичээлд:
Symbol, WeakMap, WeakSet — JavaScript-ийн өвөрмөц гурван төрөл, тэдгээрийн хаана, яагаад хэрэгтэй талаар үзнэ.