Kita sering kali perlu mengulangi tindakan.
Misalnya mengeluarkan barang dari daftar satu demi satu atau hanya menjalankan kode yang sama untuk setiap nomor dari 1 hingga 10.
Loop adalah cara untuk mengulang kode yang sama beberapa kali.
Perulangan for…of dan for…in
Pengumuman kecil untuk pembaca tingkat lanjut.
Artikel ini hanya membahas loop dasar: while
, do..while
dan for(..;..;..)
.
Jika Anda membuka artikel ini untuk mencari jenis loop lainnya, berikut petunjuknya:
Lihat…in untuk mengulang properti objek.
Lihat for…of dan iterables untuk melakukan perulangan pada array dan objek yang dapat diubah.
Jika tidak, silakan baca terus.
Perulangan while
memiliki sintaks berikut:
sementara (kondisi) { // kode // yang disebut "badan perulangan" }
Selama condition
benar, code
dari badan perulangan akan dieksekusi.
Misalnya, loop di bawah menghasilkan i
while i < 3
:
misalkan saya = 0; while (i < 3) { // menampilkan 0, lalu 1, lalu 2 peringatan( saya ); saya++; }
Eksekusi tunggal dari badan perulangan disebut iterasi . Perulangan pada contoh di atas membuat tiga iterasi.
Jika i++
tidak ada pada contoh di atas, perulangan akan berulang (secara teori) selamanya. Dalam praktiknya, browser menyediakan cara untuk menghentikan perulangan tersebut, dan di JavaScript sisi server, kita dapat menghentikan prosesnya.
Ekspresi atau variabel apa pun bisa menjadi kondisi perulangan, bukan hanya perbandingan: kondisi tersebut dievaluasi dan diubah menjadi boolean oleh while
.
Misalnya, cara yang lebih singkat untuk menulis while (i != 0)
adalah while (i)
:
misalkan saya = 3; while (i) { // ketika i menjadi 0, kondisinya menjadi falsy, dan perulangan berhenti peringatan( saya ); Saya--; }
Tanda kurung kurawal tidak diperlukan untuk badan satu baris
Jika badan perulangan mempunyai pernyataan tunggal, kita dapat menghilangkan tanda kurung kurawal {…}
:
misalkan saya = 3; sementara (i) waspada(i--);
Pemeriksaan kondisi dapat dipindahkan ke bawah badan perulangan menggunakan sintaks do..while
:
Mengerjakan { // badan lingkaran } while (kondisi);
Perulangan pertama-tama akan mengeksekusi isi, lalu memeriksa kondisinya, dan, meskipun benar, jalankan lagi dan lagi.
Misalnya:
misalkan saya = 0; Mengerjakan { peringatan( saya ); saya++; } sementara (saya < 3);
Bentuk sintaksis ini hanya boleh digunakan ketika Anda ingin badan perulangan dieksekusi setidaknya sekali, apa pun kondisinya. Biasanya, bentuk lain lebih disukai: while(…) {…}
.
Perulangan for
lebih kompleks, tetapi juga merupakan perulangan yang paling umum digunakan.
Ini terlihat seperti ini:
untuk (mulai; kondisi; langkah) { // ... badan lingkaran ... }
Mari kita pelajari arti bagian-bagian ini dengan contoh. Perulangan di bawah ini menjalankan alert(i)
for i
dari 0
hingga (tetapi tidak termasuk) 3
:
for (misalkan i = 0; i < 3; i++) { // tampilkan 0, lalu 1, lalu 2 peringatan(i); }
Mari kita periksa pernyataan for
bagian demi bagian:
bagian | ||
---|---|---|
mulai | let i = 0 | Dieksekusi satu kali saat memasuki loop. |
kondisi | i < 3 | Diperiksa sebelum setiap iterasi loop. Jika salah, perulangan berhenti. |
tubuh | alert(i) | Berjalan lagi dan lagi selama kondisinya benar. |
melangkah | i++ | Dieksekusi setelah body pada setiap iterasi. |
Algoritma loop umum bekerja seperti ini:
Jalankan dimulai → (jika kondisi → jalankan body dan run step) → (jika kondisi → jalankan body dan run step) → (jika kondisi → jalankan body dan run step) → ...
Artinya, begin
dijalankan satu kali, dan kemudian diulang: setelah setiap pengujian condition
, body
dan step
dijalankan.
Jika Anda baru mengenal loop, ada baiknya Anda kembali ke contoh dan mereproduksi cara kerjanya langkah demi langkah di selembar kertas.
Inilah yang sebenarnya terjadi dalam kasus kami:
// untuk (biarkan i = 0; i < 3; i++) waspada(i) // jalankan mulai misalkan saya = 0 // jika kondisi → jalankan body dan jalankan langkah jika (i < 3) { peringatan(i); saya++ } // jika kondisi → jalankan body dan jalankan langkah jika (i < 3) { peringatan(i); saya++ } // jika kondisi → jalankan body dan jalankan langkah jika (i < 3) { peringatan(i); saya++ } // ...selesai, karena sekarang i == 3
Deklarasi variabel sebaris
Di sini, variabel “counter” i
dideklarasikan tepat di loop. Ini disebut deklarasi variabel “inline”. Variabel tersebut hanya terlihat di dalam loop.
untuk (misalkan i = 0; i < 3; i++) { peringatan(i); // 0, 1, 2 } peringatan(i); // error, tidak ada variabel seperti itu
Daripada mendefinisikan variabel, kita bisa menggunakan variabel yang sudah ada:
misalkan saya = 0; for (i = 0; i < 3; i++) { // gunakan variabel yang sudah ada peringatan(i); // 0, 1, 2 } peringatan(i); // 3, terlihat, karena dideklarasikan di luar loop
Bagian mana pun dari for
dapat dilewati.
Misalnya, kita dapat menghilangkan begin
jika kita tidak perlu melakukan apa pun pada permulaan perulangan.
Seperti di sini:
misalkan saya = 0; // kita sudah mendeklarasikan dan menetapkannya for(; i < 3; i++) {// tidak perlu "mulai" peringatan( saya ); // 0, 1, 2 }
Kami juga dapat menghapus bagian step
:
misalkan saya = 0; untuk (; saya < 3;) { peringatan( saya++ ); }
Ini membuat perulangan identik dengan while (i < 3)
.
Kita sebenarnya dapat menghapus semuanya, menciptakan loop tak terbatas:
untuk (;;) { // mengulangi tanpa batas }
Harap dicatat bahwa keduanya for
titik koma ;
harus hadir. Jika tidak, akan terjadi kesalahan sintaksis.
Biasanya, sebuah loop keluar ketika kondisinya menjadi falsy.
Tapi kita bisa memaksa keluar kapan saja menggunakan direktif break
khusus.
Misalnya, perulangan di bawah ini menanyakan serangkaian angka kepada pengguna, “putus” ketika tidak ada nomor yang dimasukkan:
misalkan jumlah = 0; sementara (benar) { biarkan nilai = +prompt("Masukkan angka", ''); if (!value) rusak; // (*) jumlah += nilai; } alert('Jumlah: '+jumlah);
Direktif break
diaktifkan pada baris (*)
jika pengguna memasukkan baris kosong atau membatalkan input. Ini menghentikan perulangan dengan segera, meneruskan kontrol ke baris pertama setelah perulangan. Yakni, alert
.
Kombinasi “loop tak terbatas + break
sesuai kebutuhan” sangat bagus untuk situasi ketika kondisi loop harus diperiksa bukan di awal atau akhir loop, tetapi di tengah atau bahkan di beberapa tempat di tubuhnya.
Perintah continue
adalah “versi yang lebih ringan” dari break
. Itu tidak menghentikan keseluruhan putaran. Sebaliknya, ini menghentikan iterasi saat ini dan memaksa loop untuk memulai yang baru (jika kondisinya memungkinkan).
Kita dapat menggunakannya jika kita sudah selesai dengan iterasi saat ini dan ingin melanjutkan ke iterasi berikutnya.
Perulangan di bawah ini menggunakan continue
untuk hanya menghasilkan nilai ganjil:
untuk (misalkan i = 0; i < 10; i++) { // jika benar, lewati bagian tubuh yang tersisa jika (i % 2 == 0) lanjutkan; peringatan(i); // 1, lalu 3, 5, 7, 9 }
Untuk nilai genap i
, direktif continue
menghentikan eksekusi isi dan meneruskan kontrol ke iterasi for
berikutnya (dengan nomor berikutnya). Jadi alert
hanya dipanggil untuk nilai ganjil.
Perintah continue
membantu mengurangi penumpukan
Perulangan yang menunjukkan nilai ganjil akan terlihat seperti ini:
untuk (misalkan i = 0; i < 10; i++) { jika (saya % 2) { peringatan( saya ); } }
Dari segi teknis, ini identik dengan contoh di atas. Tentunya, kita cukup membungkus kode dalam blok if
daripada menggunakan continue
.
Namun sebagai efek sampingnya, hal ini menciptakan satu tingkat penyarangan lagi (panggilan alert
di dalam kurung kurawal). Jika kode di dalam if
lebih panjang dari beberapa baris, hal ini dapat menurunkan keterbacaan secara keseluruhan.
Tidak ada break/continue
ke sisi kanan '?'
Harap dicatat bahwa konstruksi sintaksis yang bukan ekspresi tidak dapat digunakan dengan operator ternary ?
. Secara khusus, arahan seperti break/continue
tidak diperbolehkan di sana.
Misalnya, jika kita mengambil kode ini:
jika (saya > 5) { peringatan(i); } kalau tidak { melanjutkan; }
…dan tulis ulang menggunakan tanda tanya:
(saya > 5) ? peringatan(i): lanjutkan; // lanjutkan tidak diperbolehkan di sini
…berhenti bekerja: ada kesalahan sintaksis.
Ini hanyalah alasan lain untuk tidak menggunakan operator tanda tanya ?
bukannya if
.
Terkadang kita perlu keluar dari beberapa loop bersarang sekaligus.
Misalnya, pada kode di bawah ini kita mengulang i
dan j
, meminta koordinat (i, j)
dari (0,0)
ke (2,2)
:
untuk (misalkan i = 0; i < 3; i++) { untuk (misalkan j = 0; j < 3; j++) { let input = prompt(`Nilai pada koordinat (${i},${j})`, ''); // bagaimana jika kita ingin keluar dari sini ke Selesai (di bawah)? } } alert('Selesai!');
Kita memerlukan cara untuk menghentikan proses jika pengguna membatalkan input.
break
biasa setelah input
hanya akan memutus loop dalam. Itu tidak cukup – label, datanglah untuk menyelamatkan!
Label adalah pengidentifikasi dengan titik dua sebelum perulangan:
labelNama: untuk (...) { ... }
Pernyataan break <labelName>
pada perulangan di bawah ini dipecah menjadi label:
luar: untuk (misalkan i = 0; i < 3; i++) { untuk (misalkan j = 0; j < 3; j++) { let input = prompt(`Nilai pada koordinat (${i},${j})`, ''); // jika string kosong atau dibatalkan, keluar dari kedua loop if (!input) pecah luar; // (*) // melakukan sesuatu dengan nilai... } } alert('Selesai!');
Pada kode di atas, break outer
mencari label bernama outer
dan keluar dari loop tersebut.
Jadi kontrolnya langsung dari (*)
ke alert('Done!')
.
Kita juga dapat memindahkan label ke baris terpisah:
luar: untuk (misalkan i = 0; i < 3; i++) { ... }
Perintah continue
juga dapat digunakan dengan label. Dalam hal ini, eksekusi kode melompat ke iterasi berikutnya dari loop berlabel.
Label tidak memungkinkan untuk “melompat” ke mana pun
Label tidak memperbolehkan kita melompat ke sembarang tempat dalam kode.
Misalnya, hal ini tidak dapat dilakukan:
label rusak; // lompat ke label di bawah (tidak berfungsi) label: untuk (...)
Arahan break
harus berada di dalam blok kode. Secara teknis, blok kode berlabel apa pun dapat digunakan, misalnya:
label: { // ... label rusak; // berhasil // ... }
…Meskipun, 99,9% waktu break
digunakan di dalam loop, seperti yang telah kita lihat pada contoh di atas.
continue
hanya dapat dilakukan dari dalam satu lingkaran.
Kami membahas 3 jenis loop:
while
– Kondisi diperiksa sebelum setiap iterasi.
do..while
– Kondisi diperiksa setelah setiap iterasi.
for (;;)
– Kondisi diperiksa sebelum setiap iterasi, pengaturan tambahan tersedia.
Untuk membuat perulangan “tak terbatas”, biasanya digunakan konstruksi while(true)
. Perulangan seperti itu, sama seperti perulangan lainnya, dapat dihentikan dengan direktif break
.
Jika kita tidak ingin melakukan apa pun pada iterasi saat ini dan ingin meneruskan ke iterasi berikutnya, kita dapat menggunakan direktif continue
.
break/continue
label dukungan sebelum loop. Label adalah satu-satunya cara untuk break/continue
untuk keluar dari loop bersarang untuk menuju ke loop luar.
pentingnya: 3
Berapa nilai terakhir yang diperingatkan oleh kode ini? Mengapa?
misalkan saya = 3; sementara (i) { waspada( saya-- ); }
Jawabannya: 1
.
misalkan saya = 3; sementara (i) { waspada( saya-- ); }
Setiap iterasi loop berkurang i
sebesar 1
. Pemeriksaan while(i)
menghentikan perulangan ketika i = 0
.
Oleh karena itu, langkah-langkah perulangan membentuk urutan berikut (“perulangan terbuka”):
misalkan saya = 3; peringatan(saya--); // tampilkan 3, turunkan i menjadi 2 alert(i--) // tampilkan 2, turunkan i menjadi 1 alert(i--) // menampilkan 1, menurunkan i menjadi 0 // selesai, while(i) check menghentikan perulangan
pentingnya: 4
Untuk setiap iterasi perulangan, tuliskan nilai yang dihasilkannya lalu bandingkan dengan solusinya.
Kedua loop alert
nilai yang sama, atau tidak?
Bentuk awalan ++i
:
misalkan saya = 0; sementara (++i < 5) peringatan( i );
Bentuk postfix i++
misalkan saya = 0; sementara (i++ < 5) peringatan( i );
Tugas ini menunjukkan bagaimana bentuk postfix/prefix dapat memberikan hasil yang berbeda ketika digunakan dalam perbandingan.
Dari 1 hingga 4
misalkan saya = 0; sementara (++i < 5) peringatan( i );
Nilai pertama adalah i = 1
, karena ++i
terlebih dahulu menambah i
dan kemudian mengembalikan nilai baru. Jadi perbandingan pertama adalah 1 < 5
dan alert
menunjukkan 1
.
Kemudian ikuti 2, 3, 4…
– nilainya muncul satu demi satu. Perbandingannya selalu menggunakan nilai pertambahan, karena ++
berada sebelum variabel.
Akhirnya, i = 4
bertambah menjadi 5
, perbandingan while(5 < 5)
gagal, dan perulangan berhenti. Jadi 5
tidak ditampilkan.
Dari 1 hingga 5
misalkan saya = 0; sementara (i++ < 5) peringatan( i );
Nilai pertama lagi i = 1
. Bentuk postfix i++
menambah i
dan kemudian mengembalikan nilai lama , sehingga perbandingan i++ < 5
akan menggunakan i = 0
(berlawanan dengan ++i < 5
).
Namun panggilan alert
itu terpisah. Ini adalah pernyataan lain yang dijalankan setelah kenaikan dan perbandingan. Jadi mendapat arus i = 1
.
Kemudian ikuti 2, 3, 4…
Mari kita berhenti pada i = 4
. Bentuk awalan ++i
akan menambahnya dan menggunakan 5
sebagai perbandingan. Tapi di sini kita memiliki bentuk postfix i++
. Jadi itu menambah i
menjadi 5
, tetapi mengembalikan nilai lama. Oleh karena itu perbandingannya sebenarnya while(4 < 5)
– benar, dan kontrol berlanjut ke alert
.
Nilai i = 5
adalah yang terakhir, karena pada langkah selanjutnya while(5 < 5)
salah.
pentingnya: 4
Untuk setiap loop, tuliskan nilai mana yang akan ditampilkan. Lalu bandingkan dengan jawabannya.
Kedua loop alert
nilai yang sama atau tidak?
Bentuk postfix:
untuk (misalkan i = 0; i < 5; i++) waspada( i );
Bentuk awalan:
untuk (biarkan i = 0; i < 5; ++i) waspada( i );
Jawabannya: dari 0
hingga 4
dalam kedua kasus.
untuk (biarkan i = 0; i < 5; ++i) waspada( i ); untuk (misalkan i = 0; i < 5; i++) waspada( i );
Itu dapat dengan mudah dikurangkan dari algoritma for
:
Jalankan sekali i = 0
sebelum semuanya (mulai).
Periksa kondisi i < 5
Jika true
– jalankan loop body alert(i)
, lalu i++
Kenaikan i++
dipisahkan dari pemeriksaan kondisi (2). Itu hanyalah pernyataan lain.
Nilai yang dikembalikan oleh kenaikan tidak digunakan di sini, jadi tidak ada perbedaan antara i++
dan ++i
.
pentingnya: 5
Gunakan perulangan for
untuk menghasilkan bilangan genap dari 2
hingga 10
.
Jalankan demonya
untuk (misalkan i = 2; i <= 10; i++) { jika (saya % 2 == 0) { peringatan( saya ); } }
Kami menggunakan operator “modulo” %
untuk mendapatkan sisanya dan memeriksa kemerataannya di sini.
pentingnya: 5
Tulis ulang kode dengan mengubah perulangan for
menjadi while
tanpa mengubah perilakunya (outputnya harus tetap sama).
untuk (misalkan i = 0; i < 3; i++) { peringatan( `angka ${i}!` ); }
misalkan saya = 0; sementara (saya < 3) { peringatan( `angka ${i}!` ); saya++; }
pentingnya: 5
Tulis perulangan yang meminta angka lebih besar dari 100
. Jika pengunjung memasukkan nomor lain – minta mereka untuk memasukkan lagi.
Perulangan harus meminta nomor sampai pengunjung memasukkan nomor lebih besar dari 100
atau membatalkan input/memasukkan baris kosong.
Disini kita asumsikan pengunjung hanya menginput angka saja. Tidak perlu menerapkan penanganan khusus untuk input non-numerik dalam tugas ini.
Jalankan demonya
biarkan nomor; Mengerjakan { num = prompt("Masukkan angka lebih dari 100?", 0); } while (angka <= 100 && angka);
Perulangan do..while
.. while berulang ketika kedua pemeriksaan benar:
Centang num <= 100
– yaitu, nilai yang dimasukkan masih tidak lebih besar dari 100
.
Tanda centang && num
salah jika num
bernilai null
atau string kosong. Kemudian perulangan while
juga berhenti.
PS Jika num
adalah null
maka num <= 100
adalah true
, jadi tanpa pemeriksaan ke-2, loop tidak akan berhenti jika pengguna mengklik BATAL. Kedua pemeriksaan tersebut diperlukan.
pentingnya: 3
Suatu bilangan bulat yang lebih besar dari 1
disebut bilangan prima jika bilangan tersebut tidak dapat dibagi tanpa sisa oleh apapun kecuali 1
dan bilangan itu sendiri.
Dengan kata lain, n > 1
adalah bilangan prima jika tidak dapat habis dibagi oleh apapun kecuali 1
dan n
.
Misalnya, 5
adalah bilangan prima karena tidak dapat dibagi tanpa sisa oleh 2
, 3
, dan 4
.
Tulis kode yang menghasilkan bilangan prima dalam interval dari 2
hingga n
.
Untuk n = 10
hasilnya adalah 2,3,5,7
.
PS Kode harus berfungsi untuk n
apa pun, tidak sulit disesuaikan untuk nilai tetap apa pun.
Ada banyak algoritma untuk tugas ini.
Mari kita gunakan loop bersarang:
Untuk setiap i pada interval { periksa apakah saya memiliki pembagi dari 1..i jika ya => nilainya bukan bilangan prima jika tidak => nilainya bilangan prima, tunjukkan }
Kode menggunakan label:
misalkan n = 10; berikutnyaPerdana: for (misalkan i = 2; i <= n; i++) { // untuk setiap i... for (misalkan j = 2; j < i; j++) {// carilah pembagi.. jika (i % j == 0) lanjutkan nextPrime; // bukan bilangan prima, lanjutkan ke i } peringatan( saya ); // bilangan prima }
Ada banyak ruang untuk mengoptimalkannya. Misalnya, kita dapat mencari pembagi dari 2
hingga akar kuadrat dari i
. Namun, jika kita ingin benar-benar efisien untuk interval yang besar, kita perlu mengubah pendekatan dan mengandalkan matematika tingkat lanjut dan algoritme kompleks seperti Saringan kuadrat, Saringan bidang bilangan umum, dll.