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 == 3Deklarasi 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 ituDaripada 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.