Μεταβλητές και σταθερές
Σε αυτή την ενότητα θα μιλήσουμε για τις μεταβλητές στον προγραμματισμό και θα δούμε ποιες είναι οι ιδιότητες και τα χαρακτηριστικά τους στην JavaScript.
Το επεισόδιο στο YouTube
Εισαγωγή
Στην προηγούμενη ενότητα αναφερθήκαμε στην έννοια της τιμής στον προγραμματισμό, καθώς και στους πρωτογενείς τύπους δεδομένων (primitive data types) που υποστηρίζονται από την JavaScript και που μπορεί να λάβει μια τιμή.
Επιγραμματικά, οι υποστηριζόμενοι τύποι δεδομένων στην JavaScript είναι οι εξής:
Τύπος | Χρησιμοποιείται για | Αναπαράσταση |
---|---|---|
Number | ακέραιους αριθμούς (integers ) και αριθμούς κινητής υποδιαστολής (floats ) | 1 3.13 -20 |
String | ακολουθίες χαρακτήρων (συμβολοσειρές) που περικλείονται σε μονά ' ή διπλά " εισαγωγικά ή backticks ` | "Jason" 'hello world' `javascript` |
Boolean | αληθής και ψευδής τιμές | true false |
Null | κενή τιμή | null |
Undefined | μή ύπαρξη τιμής ή μή ορισμένη τιμή | undefined |
BigInt | ακέραιους αριθμούς που ξεπερνούν την μέγιστη τιμή που μπορεί να υποστηρίξει ο τύπος Number | BigInt("90071992547409910") 90071992547409910n |
Symbol | μοναδικά και αμετάβλητα identifiers που χρησιμοποιούνται ως κλειδιά αντικειμένων (object properties) | Symbol("foo") |
Ποιος ο ρόλος των μεταβλητών;
Στην προηγούμενη ενότητα της σειράς Προγραμματισμός από το Μηδέν, είδαμε πώς μπορούμε να ορίσουμε τιμές στην κονσόλα (console) των DevTools του Chrome.
Οι τιμές αυτές ήταν εφήμερες τιμές (ephemeral values), με την έννοια ότι, από την στιγμή που έγιναν evaluate και μας επεστράφησαν ως output, έπαψαν να είναι διαθέσιμες για μετέπειτα χρήση στην κονσόλα· «έζησαν» προσωρινά στην μνήμη του υπολογιστή και για όσο χρονικό διάστημα είχαμε ανοιχτά τα Devtools. Αυτό σημαίνει πως αν χρειαζόμασταν να ανατρέξουμε σε μια συγκεκριμένη τιμή, τότε θα έπρεπε να την εισάγουμε σε κάθε σημείο και για όσες φορές θα μας ήταν απαραίτητη.
Όπως γίνεται αντιληπτό, στον κόσμο των υπολογιστών, όπου καλούμαστε να διαχειριστούμε έναν τεράστιο όγκο δεδομένων, αποτέλεσμα πολύπλοκων διεργασιών, κάτι τέτοιο δεν είναι πολύ χρήσιμο ή ευέλικτο. Ευτυχώς για εμάς οι γλώσσες προγραμματισμού παρέχουν τα κατάλληλα εργαλεία για να κάνουν την ζωή μας αρκετά πιο εύκολη. Τα εργαλεία αυτά ονομάζονται μεταβλητές.
Μεταξύ άλλων, οι μεταβλητές είναι απαραίτητες στον προγραμματισμό για:
- την αποθήκευση και τη διαχείριση δεδομένων κατά την εκτέλεση ενός προγράμματος,
- τον έλεγχο της ροής της εκτέλεσης προγραμμάτων, και
- τη συγγραφή κώδικα που είναι εύκολος στην παραμετροποίηση.
Στις περισσότερες γλώσσες προγραμματισμού, οι μεταβλητές δεν είναι τίποτα παραπάνω από διευθύνσεις—συμβολικά ονόματα (ελ) ή identifiers (en)—που αντιστοιχούν σε θέσεις μνήμης στον υπολογιστή. Κατά τον ορισμό τους, η μνήμη δεσμεύεται με βάση τον τύπο δεδομένων που θα αποθηκεύσουν. Οι τιμές που ανατίθενται στις μεταβλητές αντικαθιστούν τυχόν υπάρχοντα δεδομένα στην ίδια θέση μνήμης.
Κατά την εκτέλεση ενός προγράμματος, οι μεταβλητές μας επιτρέπουν να ανακτούμε και να τροποποιούμε με ευκολία τα δεδομένα που είναι αποθηκευμένα στις θέσεις μνήμης που έχουμε δεσμεύσει. Το εύρος (scope) και η διάρκεια ζωής (lifetime) μιας μεταβλητής καθορίζουν το πού και πότε τα δεδομένα αυτά θα είναι προσβάσιμα.
Τα χαρακτηριστικά των μεταβλητών διαφέρουν από γλώσσα σε γλώσσα προγραμματισμού. Η βασικές αρχές του τρόπου λειτουργίας τους, όμως, είναι η ίδια ανεξάρτητα από την γλώσσα προγραμματισμού, το λειτουργικό ή την πλατφόρμα στην οποία εκτελείται ένα πρόγραμμα.
Ακολουθεί ένα παράδειγμα για να γίνουν όλα όσα περιγράψαμε πιο εύκολα αντιληπτά.
Το παράδειγμα της βιβλιοθήκης
Ας υποθέσουμε ότι χρειαζόμαστε ένα βιβλίο από τη δανειστική βιβλιοθήκη της περιοχής μας και για αυτό το λόγο αποφασίζουμε να την επισκεφτούμε. Πάει καιρός από την τελευταία μας επίσκεψη και έτσι δεν θυμόμαστε πως είναι οργανωμένοι οι διαθέσιμοι τίτλοι βιβλίων, ούτε το πού ακριβώς βρίσκεται το βιβλίο που ψάχνουμε. Γνωρίζουμε όμως με σιγουριά πως το βιβλίο που μας ενδιαφέρει υπάρχει κάπου μέσα στην βιβλιοθήκη.
Από την στιγμή που δεν μπορούμε να ανασύρουμε από την μνήμη μας την πληροφορία για το ράφι στο οποίο βρίσκεται το βιβλίο, θα μπορούσαμε να πούμε πως η γνώση μας για την θέση του είναι εφήμερη, όπως ακριβώς και οι τιμές που εισάγαμε στην κονσόλα των DevTools.
Δίχως να χάσουμε χρόνο απευθυνόμαστε στον βιβλιοθηκονόμο, ο οποίος μετά από αναζήτηση στους καταλόγους της βιβλιοθήκης μας κατευθύνει στο σημείο —διάδρομο και ράφι— που βρίσκεται το βιβλίο που μας ενδιαφέρει. Παράλληλα, για να αποφύγουμε άσκοπες μελλοντικές αναζητήσεις για το συγκεκριμένο βιβλίο, σημειώνουμε τις πληροφορίες για την θέση του βιβλίου στο σημειωματάριο μας.
Με το να γράψουμε αυτό το σημείωμα ορίσαμε μια μεταβλητή—έστω και άθελά μας! Η μεταβλητή μας (σημείωμα) αντιστοιχεί στη μια θέση μνήμης (διάδρομος και ράφι) που έχει δεσμευτεί στην μνήμη (βιβλιοθήκη) ώστε να αποθηκεύσει μια τιμή (βιβλίο).
Με απλά λόγια, οι μεταβλητές είναι σαν τις εγγραφές σε κάποιο ευρετήριο. Μπορούμε να ορίζουμε, να διαγράφουμε ή να αλλάζουμε την τιμή μιας μεταβλητής, όπως ακριβώς μπορούμε να προσθέτουμε, να αφαιρούμε ή να ενημερώνουμε εγγραφές για την τοποθεσία των βιβλίων από το σημειωματάριο μας.
Συμβουλή
Όταν αναφερόμαστε σε μια μεταβλητή έχει επικρατήσει να ταυτίζουμε το συμβολικό όνομά (identifier) με την θέση μνήμης στο οποίο αντιστοιχεί. Λέμε για παράδειγμα: «η μεταβλητήΧ
έχει τιμή Ψ
». Αυτό που πραγματικά εννοούμε με την προηγούμενη φράση είναι πως «στη θέση μνήμης που αντιστοιχεί στο identifier Χ
έχουμε αποθηκεύσει δεδομένα που έχουν τιμή Ψ
».Μεταβλητές στην JavaScript
Σε αυτή την ενότητα θα δούμε μερικές απο τις ιδιότητες των μεταβλητών στην JavaScript.
Ορισμός μεταβλητών
Αρχικώς, για να υπάρξει μια μεταβλητή πρέπει να γίνει ο ορισμός της (variable definition). Στην JavaScript αυτό γίνεται με την χρήση των keywords var
, let
ή const
, ακολουθούμενα από το συμβολικό όνομα (identifier), τον τελεστή ανάθεσης =
(assignment operator) και την τιμή (value) που θέλουμε να της δώσουμε.
Για παράδειγμα:
Ο ενδεδειγμένος τρόπος ορισμού μεταβλητών είναι κάνοντας χρήση των keywords let
και const
. Ιστορικά, ο ορισμός μεταβλητών στην JavaScript πραγματοποιούνταν με το keyword var
, κάτι που πλέον θεωρείται ξεπερασμένο. Ο λόγος για αυτό είναι ότι υστερεί σε σχέση με τα keywords let
και const
σε ό,τι αφορά το εύρος ορισμού της μεταβλητής (variable scope), μια εννοια που θα δούμε σε επόμενη ενότητα.
Κανόνες ονοματοθεσίας μεταβλητών
Τα συμβολικά ονόματα (identifiers) που μπορούν να έχουν οι μεταβλητές υπόκεινται σε κάποιους πολύ απλούς κανόνες. Πιο συγκεκριμένα:
- δεν μπορούν να είναι δεσμευμένες λέξεις-κλειδιά (reserved words)
- δεν μπορούν να ξεκινούν με αριθμό
- δεν μπορούν να περιέχουν κενά
- δεν μπορούν να περιέχουν ειδικούς χαρακτήρες με εξαίρεση:
- την κάτω παύλα
_
(underscore) και - το σήμα του δολαρίου
$
- την κάτω παύλα
Για παράδειγμα, όλα τα παρακάτω μπορούν να χρησιμοποιηθούν ως ονόματα μεταβλητών:
Αντιθέτως, όλα τα παρακάτω θα προκαλέσουν σφάλμα κατά την εκτέλεση:
Δεσμευμένες λέξεις-κλειδιά
Οι δεσμευμένες λέξεις-κλειδιά (reserved keywords) είναι λέξεις που παίζουν ειδικό ρόλο στο συντακτικό της κάθε γλώσσας προγραμματισμού και δεν μπορούν να χρησιμοποιηθούν ως ονόματα μεταβλητών (variables) ή ονόματα συναρτήσεων (functions). Μερικές από αυτές τις λέξεις-κλειδιά στην JavaScript είναι οι ακόλουθες:if
, else
, for
, while
, switch
, case
, function
, return
, var
, let
, const
, class
, null
, true
, false
, κ.α.Στην JavaScript τα ονόματα των μεταβλητών είναι case-sensitive, δηλαδή υπάρχει διαφοροποίηση μεταξύ μεταβλητών που έχουν το ίδιο όνομα αλλά διαφορετικό τρόπο γραφής σε ό,τι αφορά τους κεφαλαίους και πεζούς χαρακτήρες.
Για παράδειγμα, οι παρακάτω μεταβλητές είναι διαφορετικές:
Όπως θα δούμε σε επόμενη ενότητα, οι ίδιοι κανόνες ονοματοθεσίας εφαρμόζονται και στα ονόματα των συναρτήσεων (functions).
Κάλεσμα μεταβλητών
Με τον όρο κάλεσμα μεταβλητής (to call a variable) εννοούμε την διεργασία κατά την οποία κάνουμε χρήση του identifier μιας μεταβλητής ώστε να ανακτήσουμε την τιμή που είναι δεσμευμένη στην μνήμη του υπολογιστή για αυτή.
Στην JavaScript και σε πολλές άλλες γλώσσες προγραμματισμού αυτό γίνεται με το να δώσουμε ως input ή να συμπεριλάβουμε σε ένα statement το identifier την μεταβλητής που μας ενδιαφέρει.
Για παράδειγμα:
Για καλέσουμε μια μεταβλητή πρέπει πρώτα να την έχουμε ορίσει, διαφορετικά θα προκύψει σφάλμα.
Για παράδειγμα:
Ανάθεση τιμής σε μεταβλητές
H JavaScript ανήκει στις λεγόμενες δυναμικές γλώσσες προγραμματισμού (dynamically typed languages). Αυτό σημαίνει ότι μπορεί να γίνει ανάθεση τιμών οποιουδήποτε τύπου δεδομένων τόσο κατά τον ορισμό μεταβλητών όσο και κατά την διάρκεια εκτέλεσης ενός προγράμματος (runtime).
Για παράδειγμα:
Ένα χαρακτηριστικό της JavaScript είναι ότι επιτρέπει τον ορισμό μεταβλητών χωρίς αναθεση τιμής. Σε αυτή την περίπτωση οι μεταβλητές αυτές λαμβάνουν αυτόματα την τιμή undefined
, τύπου Undefined, κάτι που είδαμε και στην προηγούμενη ενότητα.
Για παράδειγμα:
Δυναμικές και Στατικές Γλώσσες Προγραμματισμού
Οι γλώσσες προγραμματισμού χωρίζονται στις δυναμικές και τις στατικές (statically typed languages) με την βασική τους διαφορά να έγκειται στο πώς διαχειρίζονται τις μεταβλητές.
Όπως είδαμε, στις δυναμικές γλώσσες προγραμματισμού μια μεταβλητή δεν περιορίζεται σε ένα μόνο τύπο δεδομένων αλλά μπορεί να ενημερώνεται κατά την εκτέλεση και να λαμβάνει τιμές όλων των τύπων δεδομένων. Μερικές δημοφιλής δυναμικές γλώσσες προγραμματισμού είναι οι Python, JavaScript, Ruby, και PHP.
Στις στατικές γλώσσες ο τύπος δεδομένων που μπορεί να ανατεθεί σε μια μεταβλητή γίνεται μόνο κατά τον ορισμό της και δεν μπορεί να αλλάξει κατά την εκτέλεση. Έτσι εξασφαλίζεται η συνέπεια κατά την διάρκεια ζωής μιας μεταβλητής, κάτι που βοηθάει στην αποφυγή λαθών κατά την εκτέλεση του προγράμματος. Μερικές δημοφιλής στατικές γλώσσες προγραμματισμού είναι οι Java, C, C++, Swift, και Rust.
Διαφορά let
και const
Η βασική διαφορά μεταξύ των μεταβλητών που ορίζονται από τα keywords let
και const
είναι ότι στις μεταβλητές που έχουν οριστεί με το keyword let
επιτρέπεται η ανάθεση τιμής κατά την διάρκεια εκτέλεσης του προγράμματος:
Επίσης, επιτρέπεται ο ορισμός μιας μεταβλητής χωρίς αρχική ανάθεση τιμής:
Αυτό δεν ισχύει για τις μεταβλητές που ορίζονται από το keyword const
και αν επιχειρήσουμε κάποιες από τις παραπάνω διεργασίες θα προκύψει σφάλμα κατά την εκτέλεση και το πρόγραμμα θα τερματιστεί.
Για παράδειγμα:
Συμβουλή
Ένας εύκολος τρόπος για να θυμάστε τις διαφορές μεταξύ των δύο keywords, είναι να σκέφτεστε ότι τοconst
προέρχεται απο την λέξη constant, δηλαδή σταθερά, δηλαδή «κάτι που δεν μπορεί να αλλάξει».