Οι μεταβλητές JavaScript μπορούν να ανήκουν στο τοπικό ή παγκόσμια εμβέλεια.
Οι καθολικές μεταβλητές μπορούν να γίνουν τοπικές (ιδιωτικές) με κλείσιμο.
Μια συνάρτηση μπορεί να έχει πρόσβαση σε όλες τις μεταβλητές που ορίζονται μέσα στη συνάρτηση, όπως η εξής:
function myFunction() {
let a = 4;
return a * a;
}Δοκιμάστε το μόνοι σας →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Functions</h2>
<p>A function can access variables defined inside the function:</p>
<p id="demo"></p>
<script>
myFunction();
function myFunction() {
let a = 4;
document.getElementById("demo").innerHTML = a * a;
}
</script>
</body>
</html>
Αλλά μια συνάρτηση μπορεί επίσης να έχει πρόσβαση σε μεταβλητές που ορίζονται εκτός της συνάρτησης, όπως η εξής:
let a = 4;
function myFunction() {
return a * a;
}Δοκιμάστε το μόνοι σας →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Functions</h2>
<p>A function can access variables defined outside the function:</p>
<p id="demo"></p>
<script>
let a = 4;
myFunction();
function myFunction() {
document.getElementById("demo").innerHTML = a * a;
}
</script>
</body>
</html>
Στο τελευταίο παράδειγμα, το a είναι παγκόσμιο μεταβλητός.
Σε μια ιστοσελίδα, οι καθολικές μεταβλητές ανήκουν στη σελίδα.
Οι καθολικές μεταβλητές μπορούν να χρησιμοποιηθούν (και να αλλάξουν) από όλα τα άλλα σενάρια της σελίδας.
Στο πρώτο παράδειγμα, το a είναι τοπικό μεταβλητός.
Μια τοπική μεταβλητή μπορεί να χρησιμοποιηθεί μόνο μέσα στη συνάρτηση όπου έχει οριστεί. Το είναι κρυμμένο από άλλες συναρτήσεις και άλλους κώδικα δέσμης ενεργειών.
Παγκόσμια και τοπικές μεταβλητές με το ίδιο όνομα είναι διαφορετικές μεταβλητές. Η τροποποίηση του ενός, δεν τροποποιεί το άλλο.
Μεταβλητές που δημιουργήθηκαν χωρίς λέξη-κλειδί δήλωσης (var, ας ή const) είναι πάντα καθολικά, ακόμα κι αν έχουν δημιουργηθεί μέσα σε μια συνάρτηση.
function myFunction() {
a = 4;
}Δοκιμάστε το μόνοι σας →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Functions</h2>
<p>Variables created without a declaration keyword (var, let, or const) are always global,
even if they are created inside a function.:</p>
<p id="demo"></p>
<script>
myFunction();
document.getElementById("demo").innerHTML = a * a;
function myFunction() {
a = 4;
}
</script>
</body>
</html>
Οι καθολικές μεταβλητές ισχύουν μέχρι να απορριφθεί η σελίδα, όπως κατά την πλοήγηση σε άλλη σελίδα ή κλείστε το παράθυρο.
Τοπικός οι μεταβλητές έχουν μικρή διάρκεια ζωής. Δημιουργούνται όταν η συνάρτηση είναι καλείται και διαγράφεται όταν ολοκληρωθεί η λειτουργία.
Ας υποθέσουμε ότι θέλετε να χρησιμοποιήσετε μια μεταβλητή για να μετρήσετε κάτι και θέλετε αυτό ο μετρητής να είναι διαθέσιμος σε όλες τις λειτουργίες.
Θα μπορούσατε να χρησιμοποιήσετε μια καθολική μεταβλητή και μια συνάρτηση για να αυξήσετε τον μετρητή:
// Initiate counter
let counter = 0;
// Function to increment
counter
function add() {
counter += 1;
}
// Call add() 3 times
add();
add();
add();
// The counter should now be 3Δοκιμάστε το μόνοι σας →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Function Closures</h2>
<p>Counting with a global variable.</p>
<p id="demo"></p>
<script>
// Initiate counter
let counter = 0;
// Function to increment counter
function add() {
counter += 1;
}
// Call add() 3 times
add();
add();
add();
// The counter should now be 3
document.getElementById("demo").innerHTML = "The counter is: " + counter;
</script>
</body>
</html>
Υπάρχει ένα πρόβλημα με την παραπάνω λύση: Οποιοσδήποτε κωδικός στη σελίδα μπορεί να αλλάξει τον μετρητή, χωρίς καλώντας add().
Ο μετρητής πρέπει να είναι τοπικός στη συνάρτηση add(), για να αποτρέψει την αλλαγή άλλου κώδικα το:
// Initiate counter
let counter = 0;
// Function to increment
counter
function add() {
let counter = 0;
counter += 1;
}
//
Call add() 3 times
add();
add();
add();
//The counter should
now be 3. But it is 0Δοκιμάστε το μόνοι σας →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Function Closures</h2>
<p>Counting with a local variable.</p>
<p id="demo"></p>
<script>
// Initiate counter
let counter = 0;
// Function to increment counter
function add() {
let counter = 0;
counter += 1;
}
// Call add() 3 times
add();
add();
add();
// The result is not 3 because you mix up the globaland local counter
document.getElementById("demo").innerHTML = "The counter is: " + counter;
</script>
</body>
</html>
Δεν λειτούργησε επειδή εμφανίζουμε τον καθολικό μετρητή αντί για τον τοπικό μετρητής.
Μπορούμε να αφαιρέσουμε τον καθολικό μετρητή και να αποκτήσουμε πρόσβαση στον τοπικό μετρητή αφήνοντας το η συνάρτηση το επιστρέφει:
// Function to increment
counter
function add() {
let counter = 0;
counter += 1;
return counter;
}
//
Call add() 3 times
add();
add();
add();
//The counter should
now be 3. But it is 1.Δοκιμάστε το μόνοι σας →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Closures</h2>
<p>Counting with a local variable.</p>
<button type="button" onclick="myFunction()">Count!</button>
<p id="demo">0</p>
<script>
// Function to increment counter
function add() {
let counter = 0;
counter += 1;
return counter;
}
// Trying to increment the counter
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>
Δεν λειτούργησε επειδή επαναφέραμε τον τοπικό μετρητή κάθε φορά που καλούμε το λειτουργία.
Μια εσωτερική συνάρτηση JavaScript μπορεί να το λύσει αυτό.
Όλες οι λειτουργίες έχουν πρόσβαση στο παγκόσμιο εύρος.
Στην πραγματικότητα, στο JavaScript, όλες οι συναρτήσεις έχουν πρόσβαση στο εύρος "από πάνω" τους.
Η JavaScript υποστηρίζει ένθετες λειτουργίες. Οι ένθετες λειτουργίες έχουν πρόσβαση στο εύρος «πάνω» τους.
Σε αυτό το παράδειγμα, η εσωτερική συνάρτηση plus() έχει πρόσβαση στη μεταβλητή counter στη γονική συνάρτηση:
function add() {
let counter = 0;
function plus() {counter += 1;}
plus();
return counter;
}Δοκιμάστε το μόνοι σας →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Function Closures</h2>
<p>Counting with a local variable.</p>
<p id="demo">0</p>
<script>
document.getElementById("demo").innerHTML = add();
function add() {
let counter = 0;
function plus() {counter += 1;}
plus();
return counter;
}
</script>
</body>
</html>
Αυτό θα μπορούσε να είχε λύσει το δίλημμα του μετρητή, αν μπορούσαμε να φτάσουμε στο plus() λειτουργία από έξω.
Πρέπει επίσης να βρούμε έναν τρόπο να εκτελέσουμε το counter=0 μόνο μία φορά.
Χρειαζόμαστε ένα κλείσιμο.
Θυμάστε τις λειτουργίες αυτο-επίκλησης; Τι κάνει αυτή η λειτουργία;
const add = (function () {
let counter = 0;
return function () {counter += 1; return counter}
})();
add();
add();
add();
// the counter is now 3Δοκιμάστε το μόνοι σας →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Closures</h2>
<p>Counting with a local variable.</p>
<button type="button" onclick="myFunction()">Count!</button>
<p id="demo">0</p>
<script>
const add = (function () {
let counter = 0;
return function () {counter += 1; return counter;}
})();
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>
Η μεταβλητή add εκχωρείται στην τιμή επιστροφής μιας αυτο-επίκλησης λειτουργία.
Η λειτουργία αυτο-επίκλησης εκτελείται μόνο μία φορά. Ορίζει τον μετρητή στο μηδέν (0), και επιστρέφει μια έκφραση συνάρτησης.
Με αυτόν τον τρόπο η προσθήκη γίνεται συνάρτηση. Το "υπέροχο" μέρος είναι ότι μπορεί να έχει πρόσβαση ο μετρητής στο γονικό πεδίο.
Αυτό ονομάζεται κλείσιμο JavaScript. Το καθιστά δυνατό για μια συνάρτηση να έχει μεταβλητές "ιδιωτικές".
Ο μετρητής προστατεύεται από το εύρος της ανώνυμης λειτουργίας, και μπορεί να αλλάξει μόνο χρησιμοποιώντας τη λειτουργία προσθήκης.
Το κλείσιμο είναι μια συνάρτηση που έχει πρόσβαση στο γονικό πεδίο εφαρμογής, ακόμη και μετά το κλείσιμο της γονικής συνάρτησης.