25 август 2025

Tsikllar: while va for

Ko’pincha harakatlarni takrorlashga to’g’ri keladi.

Masalan, ro’yxatdan tovarlarni birin-ketin chiqarish yoki 1 dan 10 gacha bo’lgan har bir raqam uchun bir xil kodni ishga tushirish.

Tsikllar – bir xil kodni bir necha marta takrorlash usuli.

for…of va for…in tsikllari

Ilg’or o’quvchilar uchun kichik e’lon.

Bu maqola faqat asosiy tsikllarni qamrab oladi: while, do..while va for(..;..;..).

Agar siz bu maqolaga boshqa turdagi tsikllarni qidirib kelgan bo’lsangiz, mana ko’rsatmalar:

  • Obyekt xossalari bo’ylab tsikl uchun for…in ga qarang.
  • Massivlar va takrorlanadigan obyektlar bo’ylab tsikl uchun for…of va iterables ga qarang.

Aks holda, davom eting.

“while” tsikli

while tsikli quyidagi sintaksisga ega:

while (condition) {
  // kod
  // "tsikl tanasi" deb ataladi
}

condition haqiqiy bo’lgan vaqtda, tsikl tanasidagi kod bajariladi.

Masalan, quyidagi tsikl i < 3 bo’lgan vaqtda i ni chiqaradi:

let i = 0;
while (i < 3) {
  // 0, keyin 1, keyin 2 ni ko'rsatadi
  alert(i);
  i++;
}

Tsikl tanasining bir marta bajarilishi iteratsiya deb ataladi. Yuqoridagi misoldagi tsikl uch marta iteratsiya qiladi.

Agar yuqoridagi misolda i++ bo’lmaganida, tsikl (nazariy jihatdan) abadiy takrorlanar edi. Amalda brauzer bunday tsikllarni to’xtatish usullarini taqdim etadi va server tomonidagi JavaScript-da biz jarayonni to’xtatishimiz mumkin.

Faqat taqqoslashlar emas, har qanday ifoda yoki o’zgaruvchi tsikl sharti bo’lishi mumkin: shart baholanadi va while tomonidan boolean ga aylantiriladi.

Masalan, while (i != 0) ni yozishning qisqaroq usuli while (i):

let i = 3;
while (i) { // i 0 ga aylanganida, shart yolg'on bo'ladi va tsikl to'xtaydi
  alert( i );
  i--;
}
Bir qatorli tana uchun jingalak qavslar shart emas

Agar tsikl tanasi bitta iboraga ega bo’lsa, jingalak qavslarni {…} tashlab qo’yishimiz mumkin:

let i = 3;
while (i) alert(i--);

“do…while” tsikli

Shart tekshiruvini do..while sintaksisi yordamida tsikl tanasining pastiga ko’chirish mumkin:

do {
  // tsikl tanasi
} while (condition);

Tsikl avval tanani bajaradi, keyin shartni tekshiradi va u haqiqiy bo’lgan vaqtda uni qayta-qayta bajaradi.

Masalan:

let i = 0;
do {
  alert(i);
  i++;
} while (i < 3);

Bu sintaksis shakli faqat tsikl tanasini shart haqiqiy bo’lishidan qat’iy nazar kamida bir marta bajarishni xohlagan vaqtda ishlatilishi kerak. Odatda boshqa shakl afzal ko’riladi: while(…) {…}.

“for” tsikli

for tsikli murakkabroq, lekin u eng ko’p ishlatiladigan tsikldir.

U quyidagicha ko’rinadi:

for (begin; condition; step) {
  // ... tsikl tanasi ...
}

Misolda bu qismlarning ma’nosini o’rganamiz. Quyidagi tsikl i uchun 0 dan 3 gacha (lekin 3 ni o’z ichiga olmaydi) alert(i) ni ishga tushiradi:

for (let i = 0; i < 3; i++) {
  // 0, keyin 1, keyin 2 ni ko'rsatadi
  alert(i);
}

for ifodasini qism-qism ko’rib chiqamiz:

qism
begin let i = 0 Tsiklga kirishda bir marta bajariladi.
condition i < 3 Har bir tsikl iteratsiyasidan oldin tekshiriladi. Agar yolg’on bo’lsa, tsikl to’xtaydi.
body alert(i) Shart haqiqiy bo’lgan vaqtda qayta-qayta ishga tushadi.
step i++ Har bir iteratsiyada tanadan keyin bajariladi.

Umumiy tsikl algoritmi quyidagicha ishlaydi:

begin ni ishga tushiring
→ (agar condition → body ni ishga tushiring va step ni ishga tushiring)
→ (agar condition → body ni ishga tushiring va step ni ishga tushiring)
→ (agar condition → body ni ishga tushiring va step ni ishga tushiring)
→ ...

Ya’ni, begin bir marta bajariladi, keyin iteratsiya qiladi: har bir condition testidan keyin body va step bajariladi.

Agar siz tsikllarga yangi bo’lsangiz, misolga qaytib, uni qog’oz varaqida qadam-baqadam qanday ishlashini takrorlash yordam berishi mumkin.

Bizning holatimizda aynan nima sodir bo’lishi:

// for (let i = 0; i < 3; i++) alert(i)

// begin ni ishga tushiring
let i = 0;
// agar condition → body ni ishga tushiring va step ni ishga tushiring
if (i < 3) {
  alert(i);
  i++;
}
// agar condition → body ni ishga tushiring va step ni ishga tushiring
if (i < 3) {
  alert(i);
  i++;
}
// agar condition → body ni ishga tushiring va step ni ishga tushiring
if (i < 3) {
  alert(i);
  i++;
}
// ...tugadi, chunki endi i == 3
Inline o’zgaruvchi e’loni

Bu yerda “hisoblagich” o’zgaruvchisi i to’g’ridan-to’g’ri tsiklda e’lon qilingan. Bu “inline” o’zgaruvchi e’loni deb ataladi. Bunday o’zgaruvchilar faqat tsikl ichida ko’rinadi.

for (let i = 0; i < 3; i++) {
  alert(i); // 0, 1, 2
}
alert(i); // xato, bunday o'zgaruvchi yo'q

O’zgaruvchi aniqlash o’rniga, mavjud bo’lganini ishlatishimiz mumkin:

let i = 0;

for (i = 0; i < 3; i++) { // mavjud o'zgaruvchini ishlatish
  alert(i); // 0, 1, 2
}

alert(i); // 3, ko'rinadi, chunki tsikldan tashqarida e'lon qilingan

Qismlarni tashlab qo’yish

for ning har qanday qismini tashlab qo’yish mumkin.

Masalan, agar tsikl boshida hech narsa qilishga hojat bo’lmasa, begin ni tashlab qo’yishimiz mumkin.

Bu yerda:

let i = 0; // bizda i allaqachon e'lon qilingan va tayinlangan

for (; i < 3; i++) {
  // "begin" ga hojat yo'q
  alert(i); // 0, 1, 2
}

step qismini ham olib tashlashimiz mumkin:

let i = 0;

for (; i < 3; ) {
  alert(i++);
}

Bu tsiklni while (i < 3) ga bir xil qiladi.

Aslida hamma narsani olib tashlash mumkin, cheksiz tsikl yaratish:

for (;;) {
  // cheksiz takrorlanadi
}

E’tibor bering, for da ikkita nuqta-vergul ; bo’lishi kerak. Aks holda sintaksis xatosi bo’ladi.

Tsiklni buzish

Odatda tsikl sharti yolg’on bo’lganida chiqadi.

Lekin biz maxsus break direktivasi yordamida istalgan vaqtda chiqishni majburlab qo’yishimiz mumkin.

Masalan, quyidagi tsikl foydalanuvchidan bir qator raqamlarni so’raydi, hech qanday raqam kiritilmaganida “buziladi”:

let sum = 0;

while (true) {

  let value = +prompt("Raqam kiriting", '');

  if (!value) break; // (*)

  sum += value;

}
alert( 'Yig\'indi: ' + sum );

break direktivasi (*) qatorida faollashadi, agar foydalanuvchi bo’sh qator kiritsa yoki kiritishni bekor qilsa. U tsiklni darhol to’xtatadi va boshqaruvni tsikldan keyingi birinchi qatorga o’tkazadi. Ya’ni, alert.

“Cheksiz tsikl + kerak bo’lganda break” kombinatsiyasi tsikl shartini tsiklning boshida yoki oxirida emas, balki o’rtasida yoki hatto tananing bir necha joyida tekshirish kerak bo’lgan vaziyatlar uchun juda yaxshi.

Keyingi iteratsiyaga davom eting

continue direktivasi break ning “engilroq versiyasi”. U butun tsiklni to’xtatmaydi. Buning o’rniga, u joriy iteratsiyani to’xtatadi va tsiklni yangisini boshlashga majbur qiladi (agar shart ruxsat bersa).

Agar joriy iteratsiya bilan ishimiz tugagan bo’lsa va keyingisiga o’tishni istasak, undan foydalanishimiz mumkin.

Quyidagi tsikl faqat toq qiymatlarni chiqarish uchun continue dan foydalanadi:

for (let i = 0; i < 10; i++) {

  // agar haqiqiy bo'lsa, tananing qolgan qismini tashlab o'ting
  if (i % 2 == 0) continue;

  alert(i); // 1, keyin 3, 5, 7, 9
}

i ning juft qiymatlari uchun continue direktivasi tanani bajarishni to’xtatadi va boshqaruvni for ning keyingi iteratsiyasiga (keyingi raqam bilan) o’tkazadi. Shunday qilib alert faqat toq qiymatlar uchun chaqiriladi.

continue direktivasi joylashishni kamaytiradi

Toq qiymatlarni ko’rsatadigan tsikl quyidagicha ko’rinishi mumkin:

for (let i = 0; i < 10; i++) {
  if (i % 2) {
    alert(i);
  }
}

Texnik nuqtai nazardan, bu yuqoridagi misolga bir xil. Albatta, biz continue ishlatish o’rniga kodni if blokiga o’rashimiz mumkin.

Lekin yon ta’sir sifatida, bu yana bir darajali joylashish yaratdi (alert chaqiruvi jingalak qavslar ichida). Agar if ichidagi kod bir necha qatordan uzun bo’lsa, bu umumiy o’qish qobiliyatini kamaytirishi mumkin.

‘?’ ning o’ng tomonida break/continue yo’q

E’tibor bering, ifoda bo’lmagan sintaksis konstruksiyalarni ternary operator ? bilan ishlatib bo’lmaydi. Xususan, break/continue kabi direktivalarga u yerda ruxsat berilmaydi.

Masalan, agar biz ushbu kodni olsak:

if (i > 5) {
  alert(i);
} else {
  continue;
}

…va uni savol belgisi yordamida qayta yozsak:

(i > 5) ? alert(i) : continue; // continue bu yerda ruxsat etilmaydi

…u ishlamay qoladi: sintaksis xatosi bor.

Bu if o’rniga savol belgisi operatori ? ishlatmaslikning yana bir sababi.

break/continue uchun yorliqlar

Ba’zan biz bir vaqtning o’zida bir nechta ichma-ich tsikldan chiqishimiz kerak.

Masalan, quyidagi kodda biz i va j bo’ylab tsikl qilamiz, (0,0) dan (2,2) gacha koordinatalar (i, j) uchun so’raymiz:

for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    let input = prompt(`(${i},${j}) koordinatalaridagi qiymat`, "");

    // agar biz bu yerdan Done (pastga) chiqishni istasak nima qilamiz?
  }
}

alert("Tugadi!");

Agar foydalanuvchi kiritishni bekor qilsa, jarayonni to’xtatish usuli kerak.

input dan keyingi oddiy break faqat ichki tsiklni buzadi. Bu yetarli emas – yorliqlar, yordam bering!

Yorliq – tsikldan oldin ikki nuqta bilan identifikator:

labelName: for (...) {
  ...
}

Quyidagi tsikldagi break <labelName> ifodasi yorliqqa chiqadi:

outer: for (let i = 0; i < 3; i++) {

  for (let j = 0; j < 3; j++) {

    let input = prompt(`(${i},${j}) koordinatalaridagi qiymat`, '');

    // agar bo'sh satr yoki bekor qilingan bo'lsa, ikkala tsikldan ham chiqing
    if (!input) break outer; // (*)

    // qiymat bilan biror narsa qiling...
  }
}

alert('Tugadi!');

Yuqoridagi kodda break outer outer nomli yorliqni yuqorida qidiradi va o’sha tsikldan chiqadi.

Shunday qilib boshqaruv to’g’ridan-to’g’ri (*) dan alert('Tugadi!') ga o’tadi.

Yorliqni alohida qatorga ham ko’chirishimiz mumkin:

outer:
for (let i = 0; i < 3; i++) { ... }

continue direktivasi ham yorliq bilan ishlatilishi mumkin. Bu holda, kod bajarish yorliqlangan tsiklning keyingi iteratsiyasiga o’tadi.

Yorliqlar

Yorliqlar koddagi ixtiyoriy joyga sakrashga ruxsat bermaydi.

Masalan, buni qilish mumkin emas:

break label; // pastdagi yorliqqa sakrash (ishlamaydi)

label: for (...)

break direktivasi kod bloki ichida bo’lishi kerak. Texnik jihatdan, har qanday yorliqlangan kod bloki ishlaydi, masalan:

label: {
  // ...
  break label; // ishlaydi
  // ...
}

…Garchi, vaqtning 99.9% da break tsikllar ichida ishlatiladi, yuqoridagi misollarda ko’rganimizdek.

continue faqat tsikl ichidan mumkin.

Xulosa

Biz 3 turdagi tsiklni ko’rib chiqdik:

  • while – Har bir iteratsiyadan oldin shart tekshiriladi.
  • do..while – Har bir iteratsiyadan keyin shart tekshiriladi.
  • for (;;) – Har bir iteratsiyadan oldin shart tekshiriladi, qo’shimcha sozlamalar mavjud.

“Cheksiz” tsikl yaratish uchun odatda while(true) konstruksiyasi ishlatiladi. Bunday tsikl, boshqalar kabi, break direktivasi bilan to’xtatilishi mumkin.

Agar joriy iteratsiyada hech narsa qilishni istamasak va keyingisiga o’tishni istasak, continue direktivasidan foydalanishimiz mumkin.

break/continue tsikldan oldin yorliqlarni qo’llab-quvvatlaydi. Yorliq – break/continue ning ichma-ich tsikldan chiqib tashqi tsiklga o’tishining yagona usuli.

Vazifalar

Ushbu kod chiqaradigan oxirgi qiymat nima? Nima uchun?

let i = 3;

while (i) {
  alert(i--);
}

Javob: 1.

let i = 3;

while (i) {
  alert(i--);
}

Har bir tsiklning takrorlanishida i 1 ga kamayadi. While(i) tekshiruvi, i = 0 bo’lganda tsiklni to’xtatadi.

Demak, tsiklning qadamlari quyidagi ketma-ketlikni hosil qiladi:

let i = 3;

alert(i--); // 3 ni ko'rsatadi, i ni 2 ga kamaytiradi

alert(i--); // 2 ni ko'rsatadi, i ni 1 ga kamaytiradi

alert(i--); // 1 ni ko'rsatadi, i ni 0 ga kamaytiradi

// tugadi, while(i) tekshuruvi esa tsiklni to'xtatadi

Har bir tsikl iteratsiyasi uchun qaysi qiymatni chiqarishini yozing va keyin uni natija bilan solishtiring.

Har ikki tsikl bir xil qiymatlarni alert orqali chiqariladimi, yoki yo’qmi?

  1. ++i prefiks shakli:

    let i = 0;
    while (++i < 5) alert(i);
  2. Postfiks shakli i++

    let i = 0;
    while (i++ < 5) alert(i);

Vazifa postfiks / prefiks shakllari taqqoslashda foydalanilganda qanday qilib turli xil natijalarga olib kelishi mumkinligini namoyish etadi.

  1. 1 dan 4 gacha

    let i = 0;
    while (++i < 5) alert(i);

    Birinchi qiymat i = 1 dir, chunki ++ i avval i ni oshiradi va keyin yangi qiymatni qaytaradi. Shunday qilib, birinchi taqqoslash 1 < 5 va alert 1 ni ko’rsatadi.

    Keyin 2,3,4... ga amal qiling – qiymatlar birin-ketin paydo bo’ladi. Taqqoslash har doim ko’paytirilgan qiymatdan foydalanadi, chunki ++ o’zgaruvchandan oldin.

    Va nihoyat, i = 4 5 ga oshiriladi, taqqoslash while(5 < 5) ishlamay qoladi va tsikl to’xtaydi. Shunday qilib, 5 ko’rsatilmaydi.

  2. 1 dan 5 gacha

    let i = 0;
    while (i++ < 5) alert(i);

    Birinchi qiymat yana i = 1 dir. i++ ning postfiks shakli i ni oshiradi va keyin eski qiymatini qaytaradi, shuning uchun i++ < 5 taqqoslashida i = 0 ishlatiladi (++i < 5 ga zid).

    Ammo alert chaqiruvi alohida. Bu o’sish va taqqoslashdan keyin bajariladigan yana bir ifoda. Shunday qilib, u joriy i = 1 ni oladi.

    Keyin 2,3,4...

    Keling, i = 4 da to’xtaylik. ++i prefiksi uni ko’paytiradi va taqqoslashda 5 dan foydalanadi. Ammo bu erda biz i++ postfiksi shakliga egamiz. Shunday qilib, u i dan 5 gacha ko’tariladi, lekin eski qiymatni qaytaradi. Shuning uchun taqqoslash aslida while (4 < 5) – to’g’ri va boshqaruv alert ga o’tadi.

    i = 5 qiymati oxirgi hisoblanadi, chunki keyingi bosqichda while(5 < 5) noto’g’ri.

Har bir tsikl uchun qaysi qiymatlarni ko’rsatishini yozing. Keyin javob bilan solishtiring.

Har ikki tsikl bir xil qiymatlarni qaytaradimi alert yoki yo’qmi?

  1. Postfiks shakli:

    for (let i = 0; i < 5; i++) alert(i);
  2. Prefiks shakli:

    for (let i = 0; i < 5; ++i) alert(i);

Javob: ikkala holatda ham 0 dan 4 gacha.

for (let i = 0; i < 5; ++i) alert(i);

for (let i = 0; i < 5; i++) alert(i);

Buni for algoritmidan osongina ajratish mumkin:

  1. Hamma narsadan oldin i = 0 ifodani bir marta bajaring(boshlang).
  2. i < 5 shartni tekshiring
  3. Agar true bo’lsa – alert(i) tsiklning tanasini va keyin i++ ni bajaring

Shartni tekshirishdan (2) i++ kattalashmasi ajratilgan. Bu yana bir ifoda.

O’sish bilan qaytarilgan qiymat bu erda ishlatilmaydi, shuning uchun i++ va ++i o’rtasida farq yo’q.

for tsikldan foydalaning, 2 dan 10 gacha bo’lgan juft sonlarni chiqaring.

Namoyishni ishga tushirish

for (let i = 2; i <= 10; i++) {
  if (i % 2 == 0) {
    alert(i);
  }
}

Qoldig’ini olish va tenglikni tekshirish uchun biz % “modulo” operatoridan foydalanamiz.

for tsiklini while ga o’zgartirgan kodni uning xatti-harakatlarini o’zgartirmasdan qayta yozing(natijalar bir xil bo’lishi kerak).

for (let i = 0; i < 3; i++) {
  alert(`raqam ${i}!`);
}
let i = 0;
while (i < 3) {
  alert(`raqam ${i}!`);
  i++;
}

100 dan katta raqamni talab qiladigan tsiklni yozing. Agar mehmon boshqa raqamni kiritsa – ularni qayta kiritishni so’rang.

Tsiklga tashrif buyuruvchilar 100 dan katta raqam kiritmaguncha yoki kirishni bekor qilmaguncha/bo’sh matni kiritmaguncha raqam so’ralishi kerak.

Bu yerda biz mehmon faqat raqamlarni kiritadi deb taxmin qilishimiz mumkin. Ushbu topshiriqda raqamsiz kiritish uchun maxsus ishlov berishni amalga oshirishning hojati yo’q.

Namoyishni ishga tushirish

let num;

do {
  num = prompt("100 dan katta raqam kiritingizmi?", 0);
} while (num <= 100 && num);

Ikkala tekshiruv ham to’g’ri bo’lsa, do... while tsikli takrorlanadi:

  1. num <= 100 tekshiruvi – ya’ni kiritilgan qiymat hali ham 100 dan katta emas.
  2. num null yoki bo’sh satr bo’lganda && num tekshiruvi noto’g’ri. Agar tekshuruv noto’g’ri bolsa while tsikli ham to’xtaydi.

P.S. Agar num null bo’lsa, u holda num <= 100 haqiqiy bo’ladi, shuning uchun 2-chi tekshiruvsiz foydalanuvchi CANCEL tugmasini bosmaganicha tsikl to’xtamaydi. Ikkala tekshiruv ham talab qilinadi.

Agar 1 dan kattaroq butun son, 1 va o’zidan tashqari boshqa sonlarga qoldiqsiz bo’linmasa, u son tub deb nomlanadi.

Boshqacha qilib aytganda, n > 1 tub son hisoblanadi, agar uni 1 va n dan boshqa hech narsa bilan teng taqsimlash mumkin bo’lmasa.

Masalan, 5 tub son hisoblanadi, chunki uni 2, 3 va 4 bilan qoldiqsiz bo’lish mumkin emas.

2 dan n gacha bo`lgan oraliqda tub sonlarni chiqaradigan kodni yozing.

n = 10 uchun natija 2,3,5,7 bo’ladi.

P.S. Kod har qanday n uchun ishlashi kerak, har qanday belgilangan qiymat uchun sozlanmagan bo’lishi kerak.

Ushbu vazifani bajarish uchun ko’plab algoritmlar mavjud.

Ichki tsikldan foydalanamiz:

For each i in the interval {
  check if i has a divisor from 1..i
  if yes => the value is not a prime
  if no => the value is a prime, show it
}

Yorliqdan foydalangan holda kod:

let n = 10;

nextPrime: for (let i = 2; i <= n; i++) {
  // har bir i uchun...

  for (let j = 2; j < i; j++) {
    // bo'luvchi izlang...
    if (i % j == 0) continue nextPrime; // bosh son emas, keyingi bosqichga o'ting
  }

  alert(i); // bosh son
}

Uni optimallashtirish uchun juda ko’p yo’li mavjud. Masalan, biz 2 dan i ning kvadrat ildizigacha bo’linmalarni qidirishimiz mumkin. Ammo baribir, agar biz katta vaqt oralig’ida haqiqatan ham samarali bo’lishni istasak, biz yondashuvni o’zgartirib, Kvadratik elak kabi rivojlangan matematikaga va murakkab algoritmlarga tayanishimiz kerak, Umumiy raqamli maydonchadan tayyorlangan elak va boshqalar.

O'quv qo'llanma xaritasi

Izohlar

izoh berishdan oldin buni o'qing…
  • Agar sizda nimani yaxshilash kerakligi haqida takliflaringiz bo'lsa - iltimos, GitHub muammosini yuboring yoki izoh berish o'rniga so'rov yuboring.
  • Agar siz maqolada biror narsani tushunolmasangiz - iltimos, batafsilroq ma'lumot bering.
  • Bir nechta so'z so'zlarini kiritish uchun <code> yorlig'ini ishlating, bir nechta satrlar uchun - ularni <pre> yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepen…)