Ο βρόχος for είναι μία από τις πιο συχνά χρησιμοποιούμενες εντολές για την επαναλαμβανόμενη εκτέλεση κάποιας λογικής.
Στη JavaScript, αποτελείται από τη λέξη-κλειδί for, μια κεφαλίδα μέσα σε παρενθέσεις και ένα μπλοκ κώδικα που περιέχει το σώμα του βρόχου μέσα σε άγκιστρα.
for (initialization; condition; step) {
// code that is executed repeatedly as long as the condition is
// true
}
Η αρχικοποίηση συνήθως προετοιμάζει μια μεταβλητή μετρητή, η συνθήκη ελέγχει αν ο βρόχος πρέπει να συνεχιστεί ή να σταματήσει και το βήμα αυξάνει τον μετρητή στο τέλος κάθε επανάληψης. Τα επιμέρους μέρη της κεφαλίδας χωρίζονται με ερωτηματικά.
const list = ['a', 'b', 'c'];
for (let i = 0; i < list.length; i++) {
// code that should be executed for each item in the array
}
Και τα τρία μέρη της κεφαλίδας είναι προαιρετικά. Στην πράξη σπάνια χρησιμοποιείται αυτό. Μπορείς να διαβάσεις περισσότερα σχετικά στην τεκμηρίωση του MDN.
Οι βρόχοι for μπορούν να εμφωλευτούν, για παράδειγμα για να διατρέξεις εμφωλευμένους (πολυδιάστατους) πίνακες.
Βεβαιώσου ότι ορίζεις διαφορετική μεταβλητή μετρητή για κάθε βρόχο.
const coords = [
[1, 2],
[4, 7],
[10, -3],
];
for (let i = 0; i < coords.length; i++) {
for (let j = 0; j < coords[i].length; j++) {
// do something with coords[i][j]
}
}
Μέσα στο σώμα ενός βρόχου, μπορείς να χρησιμοποιήσεις τη λέξη-κλειδί break για να σταματήσεις εντελώς την εκτέλεση του βρόχου.
Αντίθετα, η λέξη-κλειδί continue σταματά μόνο την εκτέλεση της τρέχουσας επανάληψης και συνεχίζει με την επόμενη.
Όταν δουλεύεις με εμφωλευμένους βρόχους, τα break και continue εφαρμόζονται από προεπιλογή πάντα στον πιο εσωτερικό βρόχο.
Μπορείς να χρησιμοποιήσεις ετικέτες για να αλλάξεις αυτή τη συμπεριφορά.
Μια ετικέτα είναι ένα όνομα αναγνωριστικού που ακολουθείται από άνω και κάτω τελεία.
Τοποθετείται μπροστά από (ή πάνω από) τον βρόχο.
Μια τέτοια ετικέτα μπορεί μετά να συνδυαστεί με break ή continue για να ορίσεις σε ποιον βρόχο θα εφαρμοστεί η εντολή.
outer: for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
// ...
if (j > 5) {
continue outer;
}
// ...
}
}
Πρέπει να προσέξεις να δηλώσεις σωστά τη μεταβλητή μετρητή σου όταν έχεις να κάνεις με ασύγχρονο κώδικα.
Ας δούμε ένα παράδειγμα όπου αθροίζουμε τη μεταβλητή μετρητή ασύγχρονα με το setTimeout, αφού περιμένουμε 1 δευτερόλεπτο.
Όταν δηλώνεις τον μετρητή με var ή με let αλλά έξω από την κεφαλίδα, ο κώδικας δεν δίνει το αναμενόμενο αποτέλεσμα.
let sum = 0;
for (var i = 1; i < 4; i++) {
setTimeout(function () { sum += i; }, 1000);
}
// eventually sum will be 12 instead of 6 (1+2+3)
let sum = 0;
let i;
for (i = 1; i < 4; i++) {
setTimeout(function () { sum += i; }, 1000);
}
// same here, eventually sum will be 12 instead of 6 (1+2+3)
Σε αυτές τις δύο περιπτώσεις, το i δεν έχει εμβέλεια μόνο σε μία συγκεκριμένη επανάληψη του βρόχου.
Μέχρι να υπολογιστεί το άθροισμα, το i έχει φτάσει ήδη στην τελική του τιμή 4, κάτι που οδηγεί στο άθροισμα 4 + 4 + 4 = 12.
Αυτό το πρόβλημα μπορεί να αποφευχθεί δηλώνοντας τον μετρητή με let μέσα στην κεφαλίδα.
Αυτό έχει το ιδιαίτερο αποτέλεσμα ότι κάθε επανάληψη αποκτά τη δική της ξεχωριστή μεταβλητή let i, με εμβέλεια ακριβώς σε εκείνη τη μία εκτέλεση του σώματος του βρόχου.
Έτσι, όταν το άθροισμα υπολογιστεί αργότερα, κάθε συνάρτηση callback αναφέρεται στη δική της μεταβλητή i, που εξακολουθεί να κρατά τη σωστή τιμή.
let sum = 0;
for (let i = 1; i < 4; i++) {
setTimeout(function () { sum += i; }, 1000);
}
// eventually sum will be 6 (1+2+3) as expected