Mundarija (34)
- Bu darsda
- 1. Nega bu kerak?
- 2. for...of — qiymatlar bo'ylab
- 2.1 Satrning har bir belgisi
- 2.2 Nega bu yerda const ishlaydi?
- 2.3 Misol: unli harflarni sanash
- 2.4 break va continue ham ishlaydi
- 2.5 Emoji bilan to'g'ri ishlaydi
- 2.6 Indeks ham kerak bo'lsa-chi?
- 3. for...of nimalar bilan ishlaydi?
- 3.1 Birinchi tanishuv: massiv
- 3.2 Iterable — "aylanib chiqsa bo'ladigan"
- 4. for...in — kalitlar bo'ylab
- 4.1 Birinchi tanishuv: obyekt
- 4.2 Kalitlarni chiqarish
- 4.3 Qiymatni olish: narxlar[kalit]
- 4.4 Satrda for...in
- 5. Asosiy tuzoq: massivda for...in
- 5.1 Indekslar — satr, son emas
- 5.2 Begona kalitlar ham chiqadi
- 5.3 Meros kalitlar
- 5.4 Xulosa: qaysi siklni qachon ishlatish kerak
- 6. Ko'p uchraydigan xatolar
- 6.1 Obyektda for...of
- 6.2 narxlar.kalit — nuqta bilan olish
- 6.3 Massivda for...in va satr indekslar
- 6.4 of o'rniga in (yoki aksincha)
- 6.5 Sikl o'zgaruvchisini o'zgartirish
- 7. Mashqlar
- 1-mashq (oson): Harflarni sanash
- 2-mashq (o'rta): Baholar jurnali
- 3-mashq (qiyin): Palindrom
- 8. Real ishda
- Xulosa
JavaScript for...of va for...in: farqi va tuzoqlari
Qisqacha:
for...ofqiymatlar bo'ylab yuradi: satrning har bir belgisi, massivning har bir elementi.for...inesa obyektning kalitlari (xususiyat nomlari) bo'ylab yuradi. Qoida oddiy: satr va massiv uchun —for...of, obyekt uchun —for...in. Massivdafor...inishlatmang: u indekslarni satr sifatida beradi va begona kalitlarni ham qo'shib yuboradi.
Bu darsda
for...ofbilan satr belgilari bo'ylab indekssiz yura olasiz.for...inbilan obyekt kalitlari va qiymatlarini chiqara olasiz.ofvainfarqini bir gap bilan tushuntira olasiz.- Massivda
for...innega xavfli ekanini ko'rsatib bera olasiz. is not iterablexatosini tushunib, tuzata olasiz.
Oldin bilishingiz kerak: for sikli, break va continue, String asoslari: indeks, Ma'lumot turlari xaritasi.
1. Nega bu kerak?
for darsida satrning har bir harfini shunday olgan edik:
const ism = "Malika";
for (let i = 0; i < ism.length; i++) {
console.log(ism[i]);
}Bu ishlaydi. Lekin o'ylab ko'ring: bizga harflar kerak edi, xolos. Buning uchun esa uchta ish qildik — i ni 0 dan boshladik, i < ism.length shartini yozdik, ism[i] bilan harfni oldik. Har birida xato qilish mumkin: 1 dan boshlash, <= yozish, i ni unutish.
Hayotdan o'xshatish: ustoz sinfga daftar tarqatyapti. U "1-o'quvchi, 2-o'quvchi..." deb sanamaydi. Shunchaki "har bir o'quvchiga bittadan" beradi.
JavaScript'da ham shunday "har biri uchun" sikllari bor. Bu darsda ikkitasini o'rganamiz:
for...of— har bir qiymat uchun;for...in— har bir kalit (nom) uchun.
Nomlari o'xshash, lekin vazifasi butunlay boshqa. Ularni adashtirish — JavaScript'dagi klassik xatolardan biri.
2. for...of — qiymatlar bo'ylab
2.1 Satrning har bir belgisi
const ism = "Malika";
for (const harf of ism) {
console.log(harf);
}Konsolda:
M
a
l
i
k
aof — inglizchada "...ning". Sikl shunday o'qiladi: "ism ning har bir harfi uchun".
Hisoblagich yo'q, shart yo'q, ism[i] yo'q. Har aylanishda harf o'zgaruvchisiga navbatdagi belgi yoziladi. Belgilar tugaganda sikl o'zi to'xtaydi. Off-by-one xatosiga o'rin qolmaydi.
2.2 Nega bu yerda const ishlaydi?
for darsida ko'rgandik: for (const i = 0; ...; i++) xato beradi, chunki i++ o'zgarmasni o'zgartirishga urinadi.
for...of da esa hech narsa o'zgartirilmaydi. Har aylanishda yangi harf o'zgaruvchisi yaratiladi va unga bir marta qiymat beriladi. Shuning uchun const bemalol ishlaydi — va tavsiya etiladi. let ham ishlaydi, lekin sikl ichida harf ga yangi qiymat berish niyatingiz bo'lmasa, const yozing.
2.3 Misol: unli harflarni sanash
const xabar = "Assalomu alaykum";
let unlilar = 0;
for (const harf of xabar.toLowerCase()) {
if ("aeiou".includes(harf)) {
unlilar++;
}
}
console.log(unlilar); // 7xabar.toLowerCase()— hamma harflarni kichik harfga o'tkazadi (matnni o'zgartirish). Aks holda kattaAsanalmay qolardi."aeiou".includes(harf)— "harfshu satr ichida bormi?" (matn ichida qidirish).
for...of dan keyin istalgan satr yoki qiymat qo'yish mumkin — o'zgaruvchi ham, xabar.toLowerCase() kabi ifoda ham.
2.4 break va continue ham ishlaydi
Oldingi darsdagi break va continue for...of da ham xuddi shunday ishlaydi. Login'da bo'sh joy bo'lmasligi kerak — birinchisini topgan zahoti to'xtaymiz:
const login = "jasur 2006";
let boshJoyBor = false;
for (const belgi of login) {
if (belgi === " ") {
boshJoyBor = true;
break;
}
}
console.log(boshJoyBor); // true2.5 Emoji bilan to'g'ri ishlaydi
Unicode darsida ko'rgandik: ba'zi emojilar ichkarida ikkita "yarim belgi"dan iborat. Shuning uchun ularning length i 2 ga teng. Indeks bilan yursangiz, emoji ikkiga bo'linib ketadi. for...of esa emojini bitta butun belgi deb oladi:
const xabar = "Rahmat👍";
let sanoq = 0;
for (const belgi of xabar) {
sanoq++;
}
console.log(xabar.length); // 8
console.log(sanoq); // 7"Rahmat" — 6 harf, — 1 belgi. Haqiqiy belgilar 7 ta. length 8 deydi, for...of esa to'g'ri sanaydi. Telegram xabarlari, izohlar kabi foydalanuvchi matnlarida bu farq muhim.
2.6 Indeks ham kerak bo'lsa-chi?
for...of faqat qiymatni beradi. "Nechanchi harf?" degan savolga javob kerak bo'lsa, ikki yo'l bor:
- oddiy
for (let i = 0; ...)siklini ishlatish; for...ofichida hisoblagichni o'zingiz yuritish:let i = 0;va har aylanishdai++.
Massivlarni o'rganganda yana bir qulay usulni ko'rasiz — massiv bo'ylab yurish darsida.
Tekshirib ko'ring: Quyidagi kod nechta qator chiqaradi va ular qanday?
jsfor (const b of "Ok!") { console.log(b); }
Javob
3 ta qator: O, k, !. for...of satrning har bir belgisini — harf bo'ladimi, belgi bo'ladimi — navbat bilan beradi. Undov belgisi ham belgi.
3. for...of nimalar bilan ishlaydi?
3.1 Birinchi tanishuv: massiv
Hozircha biz asosan satrlar bilan ishladik. Lekin for...of ning asosiy "ish joyi" — massiv (array). Uni kesish darsida split natijasi sifatida ko'rgansiz. Massiv — tartiblangan qiymatlar ro'yxati. U kvadrat qavsda, vergul bilan yoziladi. Xuddi bozorga olib boradigan xarid ro'yxati kabi:
const xaridlar = ["non", "sut", "tuxum"];
for (const narsa of xaridlar) {
console.log(`Olish kerak: ${narsa}`);
}Konsolda:
Olish kerak: non
Olish kerak: sut
Olish kerak: tuxumMassivlarni massiv darsida batafsil o'rganamiz. Hozir faqat bitta narsani eslab qoling: ro'yxatning har bir elementi kerak bo'lsa — for...of.
3.2 Iterable — "aylanib chiqsa bo'ladigan"
for...of faqat iterable narsalar bilan ishlaydi. Iterable — ichidagi qiymatlarni birma-bir, tartib bilan bera oladigan narsa. Hozir bilganlaringizdan satr va massiv — iterable. Kursda keyinroq yana bir nechtasini (Map, Set kabi to'plamlarni) ko'rasiz.
Son esa iterable emas. 5 ning "ichidagi qiymatlar" degan narsa yo'q:
for (const x of 5) {
console.log(x);
}TypeError: 5 is not iterableTarjimasi: "5 — iterable emas", ya'ni "uni aylanib chiqib bo'lmaydi". 1 dan 5 gacha sanash kerak bo'lsa — oddiy for ishlating.
4. for...in — kalitlar bo'ylab
4.1 Birinchi tanishuv: obyekt
Ma'lumot turlari darsida obyekt haqida eshitgansiz, switch darsida esa uni "obyekt-lug'at" sifatida ishlatib ko'rdik. Obyekt — nomlangan qiymatlar to'plami. U jingalak qavsda, kalit: qiymat juftliklari bilan yoziladi. Xuddi choyxona menyusi kabi: taom nomi — va uning narxi.
const narxlar = { non: 4000, choy: 3000, somsa: 8000 };Bu yerda non, choy, somsa — kalitlar (keys), 4000, 3000, 8000 — ularning qiymatlari. Obyektlarni obyekt darsida to'liq o'rganamiz. Hozir bizga shu tushuncha yetadi.
4.2 Kalitlarni chiqarish
for...in obyektning har bir kaliti bo'ylab yuradi:
const narxlar = { non: 4000, choy: 3000, somsa: 8000 };
for (const kalit in narxlar) {
console.log(kalit);
}Konsolda:
non
choy
somsaE'tibor bering: narxlar emas, nomlar chiqdi. in — inglizchada "ichida". Sikl shunday o'qiladi: "narxlar ichidagi har bir kalit uchun".
4.3 Qiymatni olish: narxlar[kalit]
Kalit bilan uning qiymatini olish uchun kvadrat qavs ishlatiladi: narxlar[kalit] — switch darsidagi narxlar[ichimlik] kabi. Bu "narxlar dan shu kalitning qiymatini ber" degani. Satrdagi ism[i] ga o'xshaydi — faqat raqam o'rnida nom turadi.
const narxlar = { non: 4000, choy: 3000, somsa: 8000 };
for (const kalit in narxlar) {
console.log(`${kalit} — ${narxlar[kalit]} so'm`);
}Konsolda:
non — 4000 so'm
choy — 3000 so'm
somsa — 8000 so'mMenyudagi hamma narsaning jami narxini ham hisoblash mumkin:
const narxlar = { non: 4000, choy: 3000, somsa: 8000 };
let jami = 0;
for (const kalit in narxlar) {
jami += narxlar[kalit];
}
console.log(jami); // 15000Obyektdan qiymat olishning boshqa usullarini (nuqta orqali, narxlar.non) obyekt darsida ko'rasiz. Hozir bitta tuzoqni bilib qo'ying — u "Ko'p uchraydigan xatolar" bo'limida.
4.4 Satrda for...in
for...in ni satrga ham qo'llash mumkin. Lekin u harflarni emas, indekslarni beradi:
for (const k in "Ali") {
console.log(k);
}Konsolda:
0
1
2Harflar kerak edi — indekslar chiqdi. of va in ni adashtirsangiz, JavaScript xato bermaydi, shunchaki boshqa natija chiqaradi. Bunday xatoni topish qiyin.
Tekshirib ko'ring:
const talaba = { ism: "Jasur", yosh: 19 };uchunfor (const k in talaba) { console.log(k); }nima chiqaradi?
Javob
ism va yosh — kalitlar. "Jasur" va 19 chiqishi uchun console.log(talaba[k]) yozish kerak. for...in doim nomlarni beradi, qiymatni kalit orqali o'zingiz olasiz.
5. Asosiy tuzoq: massivda for...in
Massiv ham obyektning bir turi — uning "kalitlari" indekslar (0, 1, 2...). Shuning uchun for...in massivda ham ishlaydi. Lekin ishlatmang. Mana uch sababi.
5.1 Indekslar — satr, son emas
const mevalar = ["olma", "nok"];
for (const i in mevalar) {
console.log(i + 1);
}Konsolda:
01
111 va 2 kutgandik, 01 va 11 chiqdi. Sabab: for...in kalitlarni doim satr sifatida beradi — "0", "1". + tuzog'ini eslang: satrga son qo'shilsa, ular yopishtiriladi: "0" + 1 → "01".
5.2 Begona kalitlar ham chiqadi
Massiv obyekt bo'lgani uchun unga nomli xususiyat ham qo'shish mumkin. Buni kamdan-kam qilishadi, lekin boshqalarning kodida uchraydi:
const mevalar = ["olma", "nok"];
mevalar.izoh = "bozordan olingan";
for (const k in mevalar) {
console.log(k);
}Konsolda:
0
1
izohfor...in izoh ni ham ko'rsatdi — u meva emas-ku! for...of esa faqat elementlarni beradi:
const mevalar = ["olma", "nok"];
mevalar.izoh = "bozordan olingan";
for (const meva of mevalar) {
console.log(meva);
}Konsolda:
olma
nok5.3 Meros kalitlar
Bu eng yashirin muammo. JavaScript'da har bir massiv umumiy "ajdod"dan imkoniyatlarni meros (inheritance) qilib oladi. Xuddi farzand ota-onasidan familiya olgani kabi. Buning qanday ishlashini prototip darsida ko'rasiz.
for...in o'z kalitlarini ham, meros kalitlarni ham ko'rsatadi. Tasavvur qiling: loyihangizdagi eski kutubxona hamma massivlarning ajdodiga bitta xususiyat qo'shib qo'ygan:
// ❌ Real kodda bunday qilmang — faqat tuzoqni ko'rsatish uchun
Array.prototype.eslatma = "salom";
const mevalar = ["olma", "nok"];
for (const k in mevalar) {
console.log(k);
}Konsolda:
0
1
eslatmaSiz mevalar ga hech narsa qo'shmadingiz. Lekin for...in baribir begona eslatma ni chiqardi. Eski saytlarda bunday xatolar ko'p bo'lgan. Eng yomoni — bu kalit sizning kodingizdan emas, boshqa joydan keladi, shuning uchun uni topish qiyin.
Maslahat: Nega massivning
lengthifor...inda chiqmadi? Chunkifor...infaqat sanaladigan (enumerable) kalitlarni ko'rsatadi.lengthichki xususiyat va "sanalmaydigan" qilib belgilangan. Siz qo'shganizohvaeslatmaesa odatiy holda sanaladigan bo'ladi.
Obyektlarda ham shu muammo bor. Shuning uchun obyekt bilan ishlaganda ham ehtiyot choralari ko'riladi: Object.hasOwn bilan "bu kalit obyektning o'zinikimi?" deb tekshiriladi yoki Object.keys ishlatiladi. Bularni obyekt darsida va obyekt bo'ylab yurish darsida o'rganasiz.
5.4 Xulosa: qaysi siklni qachon ishlatish kerak
| Sikl | Nima beradi | Qachon |
|---|---|---|
for (let i ...) |
Hisoblagich (son) | Indeks kerak, sanash, teskari yurish |
for...of |
Qiymatlar | Satr, massiv — har bir element uchun |
for...in |
Kalitlar (satr) | Obyekt — har bir kalit uchun |
Oltin qoida: massivda for...in ishlatmang. Massiv uchun — for...of yoki oddiy for.
Eslab qolish uchun: for...in — indekslar va nomlar (kalitlar), for...of — qiymatlarning o'zi.
Tekshirib ko'ring:
const ballar = [90, 75];massivi uchunfor (const x in ballar) { console.log(x); }nima chiqaradi?ino'rnigaofbo'lsa-chi?
Javob
in bilan: 0 va 1 — indekslar, satr ko'rinishida. of bilan: 90 va 75 — qiymatlar. Ballar kerak bo'lgani uchun to'g'ri tanlov — for...of.
6. Ko'p uchraydigan xatolar
6.1 Obyektda for...of
const narxlar = { non: 4000, choy: 3000 };
for (const narx of narxlar) {
console.log(narx);
}TypeError: narxlar is not iterableTarjimasi: "narxlar — iterable emas". Oddiy obyektning qiymatlari tartiblangan ro'yxat emas, shuning uchun for...of uni aylana olmaydi. Tuzatish: obyekt uchun for...in ishlating. (Obyektni for...of ga "tayyorlab beradigan" Object.values va Object.entries ham bor — obyekt bo'ylab yurish darsida.)
6.2 narxlar.kalit — nuqta bilan olish
const narxlar = { non: 4000, choy: 3000 };
for (const kalit in narxlar) {
console.log(narxlar.kalit);
}Konsolda:
undefined
undefinedXato yo'q, lekin qiymatlar ham yo'q. narxlar.kalit — "narxlar dan aynan kalit degan nomli xususiyatni ber" degani. Bunday nomli kalit yo'q, natija undefined. kalit o'zgaruvchisining ichidagi nomdan foydalanish uchun kvadrat qavs kerak: narxlar[kalit].
6.3 Massivda for...in va satr indekslar
Yuqorida ko'rdik: i + 1 → "01". Belgisi: kutilgan son o'rniga g'alati "yopishgan" raqamlar. Tuzatish: massivda for...of yoki oddiy for ishlating.
6.4 of o'rniga in (yoki aksincha)
Satrda for...in — harflar o'rniga 0, 1, 2. Massivda for...in — qiymatlar o'rniga indekslar. Xato chiqmaydi, faqat natija boshqacha. Sikl g'alati natija bersa, birinchi navbatda shu so'zni tekshiring.
6.5 Sikl o'zgaruvchisini o'zgartirish
for (const harf of "abc") {
harf = harf.toUpperCase();
}TypeError: Assignment to constant variable."O'zgarmas o'zgaruvchiga qiymat berish". harf — const. Natijani yangi o'zgaruvchiga yozing: const katta = harf.toUpperCase();. Yoki natijani sikldan tashqaridagi let o'zgaruvchiga yig'ing.
7. Mashqlar
1-mashq (oson): Harflarni sanash
"Samarqand" so'zida nechta "a" harfi borligini for...of bilan sanang. Natija: 3.
Yechim
const shahar = "Samarqand";
let soni = 0;
for (const harf of shahar) {
if (harf === "a") {
soni++;
}
}
console.log(soni); // 3Indeks, length, < — hech biri kerak bo'lmadi. Katta S ham sanalishi kerak bo'lsa (masalan, "s" harfini sanasangiz), shahar.toLowerCase() ni aylaning.
2-mashq (o'rta): Baholar jurnali
Talabaning baholari obyektda berilgan:
const baholar = { matematika: 5, fizika: 4, tarix: 3, ingliz: 4 };for...in yordamida:
- Har bir fanni
matematika: 5ko'rinishida chiqaring. - O'rtacha bahoni hisoblang va oxirida
O'rtacha: 4deb chiqaring.
Ishora: ikkita yig'uvchi o'zgaruvchi kerak — baholar yig'indisi va fanlar soni. O'rtacha = yig'indi / soni.
Yechim
const baholar = { matematika: 5, fizika: 4, tarix: 3, ingliz: 4 };
let yigindi = 0;
let soni = 0;
for (const fan in baholar) {
console.log(`${fan}: ${baholar[fan]}`);
yigindi += baholar[fan];
soni++;
}
console.log(`O'rtacha: ${yigindi / soni}`);Konsolda:
matematika: 5
fizika: 4
tarix: 3
ingliz: 4
O'rtacha: 4Kalit nomi fan — ma'noli nom kodni o'qishni osonlashtiradi. Obyektda nechta kalit borligini oldindan bilmaymiz, shuning uchun soni ni sikl ichida sanadik.
3-mashq (qiyin): Palindrom
Palindrom — oldindan ham, orqadan ham bir xil o'qiladigan so'z: "kiyik", "qazaq", "non". for...of yordamida so'zni teskari aylantiring va palindrom ekanini tekshiring.
"kiyik" uchun natija: kiyik — palindrom. "olma" uchun: olma — palindrom emas (teskarisi amlo).
Ishora: let teskari = ""; dan boshlang. Har bir harfni satrning boshiga qo'shing: teskari = harf + teskari. Oxirida teskari === soz ni tekshiring (if / else yoki ternary).
Yechim
const soz = "kiyik";
let teskari = "";
for (const harf of soz) {
teskari = harf + teskari;
}
if (teskari === soz) {
console.log(`${soz} — palindrom`);
} else {
console.log(`${soz} — palindrom emas`);
}Konsolda:
kiyik — palindrom"olma" uchun kuzatuv: "o" → "lo" → "mlo" → "amlo". Har yangi harf oldinga qo'yilgani uchun tartib teskari bo'ladi. "amlo" === "olma" — false, demak palindrom emas.
soz o'zgaruvchisini "olma" ga, keyin "non" ga o'zgartirib sinab ko'ring.
8. Real ishda
for...of— zamonaviy JavaScript'dagi eng ko'p ishlatiladigan sikllardan biri. Savatdagi mahsulotlar, chatdagi xabarlar, API'dan kelgan foydalanuvchilar ro'yxati — hammasi massiv va hammasifor...ofbilan aylanadi.for...inreal kodda kamroq uchraydi. Obyektlar uchun ko'pinchaObject.keysvaObject.entriesishlatiladi — ular faqat obyektning o'z kalitlarini beradi.- Kod tekshiruvchi vositalar (masalan, ESLint — kod yozilishini tekshiradigan dastur, kursda alohida o'rganamiz) massivda
for...inni ko'pincha xato deb belgilaydi. - Meros kalitlar muammosi xavfsizlik bilan ham bog'liq: hujumchi umumiy "ajdod"ga kalit qo'shib, butun ilovani buzishga urinishi mumkin. Bu hujum prototype pollution deb ataladi — kursda alohida ko'ramiz.
Intervyularda "for...of va for...in farqi nima?" savoli juda ko'p beriladi. To'liq javob: "for...of iterable'ning qiymatlarini beradi, for...in esa obyektning sanaladigan kalitlarini — meros bo'lganlarini ham — satr sifatida beradi. Shuning uchun massivda for...in ishlatilmaydi."
Xulosa
for (const x of ...)— qiymatlar: satr belgilari, massiv elementlari. Indeks va off-by-one tashvishi yo'q.for (const k in ...)— kalitlar: obyektning xususiyat nomlari. Qiymat —obyekt[k].for...offaqat iterable bilan ishlaydi. Oddiy obyekt yoki son —TypeError: ... is not iterable.for...inkalitlarni doim satr sifatida beradi va meros kalitlarni ham ko'rsatadi.- Massivda
for...inishlatmang —for...ofyoki oddiyfortanlang. for...ofemojilarni bitta butun belgi deb sanaydi, indeks bilan yurish esa ularni bo'lib yuboradi.
Oldingi dars: break, continue va label'lar.
Keyingi dars: Funksiya e'lon qilish va chaqirish — kodni nomlab, xohlagancha qayta ishlatishni o'rganamiz.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!