Λειτουργίες JavaScript. Εκφραστική JavaScript: Λειτουργίες Λειτουργίες ως τιμές

Οι άνθρωποι πιστεύουν ότι η επιστήμη των υπολογιστών είναι μια τέχνη για ιδιοφυΐες. Στην πραγματικότητα, ισχύει το αντίθετο - απλώς πολλοί άνθρωποι κάνουν πράγματα που στέκονται το ένα πάνω στο άλλο, σαν να φτιάχνουν έναν τοίχο από μικρά βότσαλα.

Ντόναλντ Κνουθ

Έχετε ήδη δει κλήσεις λειτουργιών όπως ειδοποίηση. Οι συναρτήσεις είναι το ψωμί και το βούτυρο του προγραμματισμού JavaScript. Η ιδέα να τυλίξετε ένα κομμάτι ενός προγράμματος και να το ονομάσετε ως μεταβλητή είναι πολύ δημοφιλής. Είναι ένα εργαλείο για τη δόμηση μεγάλων προγραμμάτων, τη μείωση της επανάληψης, την εκχώρηση ονομάτων σε υπορουτίνες και την απομόνωση των υπορουτινών μεταξύ τους.

Η πιο προφανής χρήση των συναρτήσεων είναι η δημιουργία ενός νέου λεξικού. Το να βρίσκεις λέξεις για τη συνηθισμένη ανθρώπινη πεζογραφία είναι μια κακή μορφή. Σε μια γλώσσα προγραμματισμού, αυτό είναι απαραίτητο.

Ο μέσος ενήλικος ομιλητής της Ρωσίας γνωρίζει περίπου 10.000 λέξεις. Μια σπάνια γλώσσα προγραμματισμού περιέχει 10.000 ενσωματωμένες εντολές. Και το λεξιλόγιο μιας γλώσσας προγραμματισμού είναι πιο ξεκάθαρο, επομένως είναι λιγότερο ευέλικτο από μια ανθρώπινη γλώσσα. Ως εκ τούτου, συνήθως πρέπει να προσθέσουμε τα δικά μας λόγια σε αυτό για να αποφύγουμε την περιττή επανάληψη.

Ορισμός συνάρτησης

Ένας ορισμός συνάρτησης είναι ένας ορισμός κανονικής μεταβλητής, όπου η τιμή που λαμβάνει η μεταβλητή είναι η συνάρτηση. Για παράδειγμα, ο ακόλουθος κώδικας ορίζει μια μεταβλητή τετράγωνο που αναφέρεται σε μια συνάρτηση που υπολογίζει το τετράγωνο ενός δεδομένου αριθμού:

var Square = συνάρτηση(x) ( return x * x; ); console.log(square(12)); // → 144

Μια συνάρτηση δημιουργείται από μια έκφραση που ξεκινά με τη λέξη-κλειδί συνάρτησης. Οι συναρτήσεις έχουν ένα σύνολο παραμέτρων (σε αυτήν την περίπτωση, μόνο x) και ένα σώμα που περιέχει τις εντολές που πρέπει να εκτελεστούν όταν καλείται η συνάρτηση. Το σώμα μιας συνάρτησης περικλείεται πάντα σε σγουρά άγκιστρα, ακόμα κι αν αποτελείται από μία μόνο πρόταση.

Μια συνάρτηση μπορεί να έχει πολλές παραμέτρους ή και καμία. Στο παρακάτω παράδειγμα, το makeNoise δεν έχει λίστα παραμέτρων, ενώ το power έχει δύο:

Var makeNoise = function() ( console.log("Fuck!"); ); κάνουν θόρυβο(); // → Χάλια! var power = συνάρτηση (βάση, εκθέτης) ( var αποτέλεσμα = 1; for (var count = 0; count< exponent; count++) result *= base; return result; }; console.log(power(2, 10)); // → 1024

Ορισμένες συναρτήσεις επιστρέφουν μια τιμή, όπως η ισχύς και το τετράγωνο, άλλες όχι, όπως το makeNoise, το οποίο έχει μόνο μια παρενέργεια. Η δήλωση επιστροφής ορίζει την τιμή που επιστρέφεται από τη συνάρτηση. Όταν η επεξεργασία του προγράμματος φτάσει σε αυτήν την εντολή, βγαίνει αμέσως από τη συνάρτηση και επιστρέφει αυτήν την τιμή στη θέση του κώδικα από την οποία κλήθηκε η συνάρτηση. επιστροφή χωρίς έκφραση επιστρέφει απροσδιόριστη.

Παράμετροι και εύρος

Οι παράμετροι συνάρτησης είναι ακριβώς όπως οι μεταβλητές, αλλά οι αρχικές τους τιμές ορίζονται όταν καλείται η συνάρτηση και όχι στον κώδικά της.

Μια σημαντική ιδιότητα των συναρτήσεων είναι ότι οι μεταβλητές που δημιουργούνται μέσα σε μια συνάρτηση (συμπεριλαμβανομένων των παραμέτρων) είναι τοπικές εντός αυτής της συνάρτησης. Αυτό σημαίνει ότι στο παράδειγμα ισχύος, το αποτέλεσμα της μεταβλητής θα δημιουργείται κάθε φορά που καλείται η συνάρτηση και αυτές οι ξεχωριστές ενσαρκώσεις της δεν σχετίζονται μεταξύ τους με κανέναν τρόπο.

Αυτή η τοποθεσία μεταβλητών ισχύει μόνο για παραμέτρους και μεταβλητές που δημιουργούνται μέσα σε συναρτήσεις. Οι μεταβλητές που ορίζονται εκτός οποιασδήποτε συνάρτησης ονομάζονται καθολικές μεταβλητές επειδή είναι ορατές σε όλο το πρόγραμμα. Μπορείτε επίσης να έχετε πρόσβαση σε τέτοιες μεταβλητές μέσα σε μια συνάρτηση, εκτός εάν έχετε δηλώσει μια τοπική μεταβλητή με το ίδιο όνομα.

Ο παρακάτω κώδικας το δείχνει. Ορίζει και καλεί δύο συναρτήσεις που εκχωρούν μια τιμή στο x. Το πρώτο το δηλώνει ως τοπική, αλλάζοντας έτσι μόνο την τοπική μεταβλητή. Η δεύτερη δεν δηλώνει, επομένως η εργασία με x μέσα στη συνάρτηση αναφέρεται στην καθολική μεταβλητή x που ορίστηκε στην αρχή του παραδείγματος.

var x = "έξω"; var f1 = function() ( var x = "inside f1"; ); f1(); αρχείο καταγραφής κονσόλας (x); // → εξωτερικό var f2 = function() ( x = "inside f2"; ); f2(); αρχείο καταγραφής κονσόλας (x); // → μέσα στο f2

Αυτή η συμπεριφορά βοηθά στην αποφυγή τυχαίας αλληλεπίδρασης μεταξύ των λειτουργιών. Εάν όλες οι μεταβλητές χρησιμοποιήθηκαν οπουδήποτε στο πρόγραμμα, θα ήταν πολύ δύσκολο να βεβαιωθείτε ότι μια μεταβλητή δεν χρησιμοποιείται για διαφορετικούς σκοπούς. Και αν επαναχρησιμοποιούσατε μια μεταβλητή, θα συναντούσατε περίεργα εφέ όπου ο κώδικας τρίτων ανακατεύει τις τιμές της μεταβλητής σας. Αντιμετωπίζοντας τις τοπικές μεταβλητές συνάρτησης έτσι ώστε να υπάρχουν μόνο εντός της συνάρτησης, η γλώσσα καθιστά δυνατή την εργασία με συναρτήσεις σαν να ήταν χωριστά μικρά σύμπαντα, κάτι που σας επιτρέπει να μην ανησυχείτε για ολόκληρο τον κώδικα ως σύνολο.

Ένθετα πεδία

Η JavaScript διακρίνει όχι μόνο μεταξύ καθολικών και τοπικών μεταβλητών. Οι συναρτήσεις μπορούν να οριστούν εντός συναρτήσεων, με αποτέλεσμα πολλά επίπεδα τοπικότητας.

Για παράδειγμα, η ακόλουθη μάλλον χωρίς νόημα συνάρτηση περιέχει δύο ακόμη μέσα:

var landscape = συνάρτηση() ( var αποτέλεσμα = ""; var flat = συνάρτηση(μέγεθος) ( for (var count = 0; count< size; count++) result += "_"; }; var mountain = function(size) { result += "/"; for (var count = 0; count < size; count++) result += """; result += "\\"; }; flat(3); mountain(4); flat(6); mountain(1); flat(1); return result; }; console.log(landscape()); // → ___/""""\______/"\_

Οι συναρτήσεις επίπεδη και βουνό βλέπουν τη μεταβλητή του αποτελέσματος επειδή βρίσκονται μέσα στη συνάρτηση στην οποία ορίζεται. Αλλά δεν μπορούν να δουν ο ένας τις μεταβλητές καταμέτρησης του άλλου, επειδή οι μεταβλητές της μιας συνάρτησης βρίσκονται εκτός του πεδίου εφαρμογής της άλλης. Και το περιβάλλον εκτός της συνάρτησης τοπίου δεν βλέπει καμία από τις μεταβλητές που ορίζονται μέσα σε αυτήν τη συνάρτηση.

Εν ολίγοις, σε κάθε τοπικό πεδίο, μπορείτε να δείτε όλα τα πεδία που το περιέχουν. Το σύνολο των διαθέσιμων μεταβλητών μέσα σε μια συνάρτηση καθορίζεται από το μέρος όπου δηλώνεται αυτή η συνάρτηση στο πρόγραμμα. Όλες οι μεταβλητές από τα μπλοκ που περιβάλλουν τον ορισμό της συνάρτησης είναι ορατές - συμπεριλαμβανομένων εκείνων που ορίζονται στο κορυφαίο επίπεδοστο κύριο πρόγραμμα. Αυτή η προσέγγιση στα πεδία ονομάζεται λεξιλογική.

Οι άνθρωποι που έχουν σπουδάσει άλλες γλώσσες προγραμματισμού μπορεί να πιστεύουν ότι οποιοδήποτε μπλοκ περικλείεται σε σγουρά στηρίγματα δημιουργεί το δικό του τοπικό περιβάλλον. Αλλά στο JavaScript, μόνο οι συναρτήσεις δημιουργούν εύρος. Μπορείτε να χρησιμοποιήσετε αυτόνομα μπλοκ:

var κάτι = 1; ( var something = 2; // Κάντε κάτι με μεταβλητή κάτι... ) // Έξοδος από το μπλοκ...

Αλλά κάτι μέσα στο μπλοκ είναι η ίδια μεταβλητή με το εξωτερικό. Παρόλο που τέτοια μπλοκ επιτρέπονται, είναι λογικό να τα χρησιμοποιείτε μόνο για εντολές if και βρόχους.

Αν αυτό σας φαίνεται περίεργο, δεν φαίνεται μόνο σε εσάς. Η JavaScript 1.7 εισήγαγε τη λέξη-κλειδί let, η οποία λειτουργεί όπως το var, αλλά δημιουργεί μεταβλητές που είναι τοπικές σε οποιοδήποτε δεδομένο μπλοκ, όχι μόνο στη συνάρτηση.

Λειτουργεί ως τιμές

Τα ονόματα συναρτήσεων χρησιμοποιούνται συνήθως ως όνομα για ένα τμήμα ενός προγράμματος. Μια τέτοια μεταβλητή ορίζεται μια φορά και δεν αλλάζει. Έτσι είναι εύκολο να συγχέουμε μια συνάρτηση με το όνομά της.

Αλλά αυτά είναι δύο διαφορετικά πράγματα. Μια κλήση συνάρτησης μπορεί να χρησιμοποιηθεί σαν μια απλή μεταβλητή - για παράδειγμα, μπορούν να χρησιμοποιηθούν σε οποιαδήποτε έκφραση. Είναι δυνατό να αποθηκεύσετε μια κλήση συνάρτησης σε μια νέα μεταβλητή, να τη μεταβιβάσετε ως παράμετρο σε μια άλλη συνάρτηση και ούτω καθεξής. Επίσης, η μεταβλητή που αποθηκεύει την κλήση συνάρτησης παραμένει μια συνηθισμένη μεταβλητή και η τιμή της μπορεί να αλλάξει:

Var launchMissiles = συνάρτηση(τιμή) (​missileSystem. launch("παρακαλώ!"); ); if (safeMode) launchMissiles = function(value) (/* release */);

Στο Κεφάλαιο 5, θα συζητήσουμε τα υπέροχα πράγματα που μπορούν να γίνουν μεταβιβάζοντας κλήσεις συναρτήσεων σε άλλες συναρτήσεις.

Δήλωση λειτουργίας

Υπάρχει μια συντομότερη εκδοχή της έκφρασης "var Square = συνάρτηση...". Η λέξη-κλειδί συνάρτησης μπορεί να χρησιμοποιηθεί στην αρχή μιας δήλωσης:

συνάρτηση τετράγωνο(x) (επιστρέφει x * x; )

Αυτή είναι μια δήλωση συνάρτησης. Η δήλωση ορίζει τη μεταβλητή τετράγωνο και της αναθέτει τη δεδομένη συνάρτηση. Μέχρι στιγμής όλα είναι εντάξει. Υπάρχει μόνο μία παγίδα σε έναν τέτοιο ορισμό.

Console.log("Το μέλλον λέει:", future()); function future() (επιστροφή "Δεν έχουμε ΑΚΟΜΑ ιπτάμενα αυτοκίνητα.";)

Αυτός ο κωδικός λειτουργεί ακόμα κι αν η συνάρτηση δηλώνεται κάτω από τον κωδικό που τη χρησιμοποιεί. Αυτό συμβαίνει επειδή οι δηλώσεις συναρτήσεων δεν αποτελούν μέρος της κανονικής εκτέλεσης προγραμμάτων από πάνω προς τα κάτω. «Μετακινούνται» στην κορυφή του πεδίου εφαρμογής τους και μπορούν να κληθούν με οποιονδήποτε κωδικό σε αυτό το πεδίο. Αυτό μερικές φορές είναι βολικό επειδή μπορείτε να γράψετε τον κώδικα με τη σειρά που είναι πιο λογικό χωρίς να χρειάζεται να ανησυχείτε μήπως χρειαστεί να ορίσετε όλες τις παραπάνω λειτουργίες όπου χρησιμοποιούνται.

Τι συμβαίνει όμως εάν τοποθετήσουμε μια δήλωση συνάρτησης μέσα σε ένα υπό όρους μπλοκ ή βρόχο; Δεν χρειάζεται να το κάνετε αυτό. Ιστορικά, διαφορετικές πλατφόρμες για την εκτέλεση JavaScript χειρίζονταν τέτοιες περιπτώσεις με διαφορετικό τρόπο και το τρέχον πρότυπο γλώσσας το απαγορεύει. Εάν θέλετε τα προγράμματά σας να εκτελούνται με συνέπεια, χρησιμοποιήστε δηλώσεις συναρτήσεων μόνο μέσα σε άλλες συναρτήσεις ή στο κύριο πρόγραμμα.

Παράδειγμα συνάρτησης() ( συνάρτηση a() () // Κανονισμός εάν (κάτι) ( συνάρτηση β() () // Ay-yy-yy! ) )

στοίβα κλήσεων
Είναι χρήσιμο να ρίξετε μια πιο προσεκτική ματιά στον τρόπο λειτουργίας της εντολής εκτέλεσης με τις συναρτήσεις. Εδώ απλό πρόγραμμαμε πολλαπλές κλήσεις λειτουργιών:

Συνάρτηση greet(who) ( console.log("Hi, " + who); ) greet("Semyon"); console.log("Pokeda");

Επεξεργάζεται κάπως έτσι: η κλήση χαιρετισμού κάνει το πάσο να μεταβεί στην αρχή της λειτουργίας. Καλεί την ενσωματωμένη συνάρτηση console.log, η οποία παίρνει τον έλεγχο, κάνει το δικό της και επιστρέφει τον έλεγχο. Μετά φτάνει στο τέλος του χαιρετισμού, και επιστρέφει στο μέρος από το οποίο κλήθηκε. Η επόμενη γραμμή καλεί ξανά το console.log.

Σχηματικά, αυτό μπορεί να παρουσιαστεί ως εξής:

Top greet console.log χαιρετίζω top console.log top

Επειδή η συνάρτηση πρέπει να επιστρέψει από όπου κλήθηκε, ο υπολογιστής πρέπει να θυμάται το περιβάλλον από το οποίο κλήθηκε η συνάρτηση. Σε μια περίπτωση, το console.log θα πρέπει να αλλάξει ξανά σε χαιρετισμό. Σε άλλο, επιστρέφει στο τέλος του προγράμματος.

Το μέρος όπου ο υπολογιστής θυμάται το περιβάλλον ονομάζεται στοίβα. Κάθε φορά που καλείται η συνάρτηση, το τρέχον περιβάλλον ωθείται στην κορυφή της στοίβας. Όταν η συνάρτηση επιστρέφει, βγάζει το επάνω πλαίσιο από τη στοίβα και το χρησιμοποιεί για να συνεχίσει.

Η αποθήκευση στοίβας απαιτεί χώρο στη μνήμη. Όταν η στοίβα μεγαλώσει πολύ, ο υπολογιστής σταματά την εκτέλεση και εκδίδει κάτι όπως "υπερχείλιση στοίβας" ή "υπερβολικά μεγάλη αναδρομή". Ο παρακάτω κώδικας το δείχνει - θέτει στον υπολογιστή μια πολύ περίπλοκη ερώτηση που οδηγεί σε ατελείωτα πηδήματα μεταξύ δύο συναρτήσεων. Πιο συγκεκριμένα, θα ήταν άπειρα άλματα εάν ο υπολογιστής είχε μια άπειρη στοίβα. Στην πραγματικότητα, η στοίβα ξεχειλίζει.

Συνάρτηση chicken() ( return egg(); ) function egg() ( return chicken(); ) console.log(chicken() + " ήρθε πρώτος."); // → ??

Προαιρετικά επιχειρήματα
Ο παρακάτω κώδικας είναι απολύτως νόμιμος και εκτελείται χωρίς προβλήματα:

Ειδοποίηση("Γεια", "Καλησπέρα", "Γεια σε όλους!");

Επίσημα, η συνάρτηση παίρνει ένα όρισμα. Ωστόσο, όταν την αμφισβητούν έτσι, δεν παραπονιέται. Αγνοεί τα υπόλοιπα επιχειρήματα και δείχνει «Γεια».

Η JavaScript είναι πολύ επιεική όσον αφορά τον αριθμό των ορισμάτων που μεταβιβάζονται σε μια συνάρτηση. Αν περάσετε πολύ, τα επιπλέον θα αγνοηθούν. Πολύ λίγα - σε αυτά που λείπουν θα εκχωρηθεί η τιμή απροσδιόριστη.

Το μειονέκτημα αυτής της προσέγγισης είναι ότι είναι δυνατό - και μάλιστα πιθανό - να περάσει λάθος αριθμός ορισμών στη συνάρτηση και κανείς δεν θα σας παραπονεθεί για αυτό.

Το θετικό είναι ότι μπορείτε να δημιουργήσετε συναρτήσεις που λαμβάνουν προαιρετικά ορίσματα. Για παράδειγμα, στην επόμενη έκδοση της συνάρτησης ισχύος, μπορεί να κληθεί με δύο και με ένα όρισμα - στην τελευταία περίπτωση, ο εκθέτης θα είναι ίσος με δύο και η συνάρτηση λειτουργεί σαν τετράγωνο.

Ισχύς συνάρτησης (βάση, εκθέτης) ( αν (εκθέτης == απροσδιόριστος) εκθέτης = 2; αποτέλεσμα var = 1; για (αριθμός var = 0; μέτρηση< exponent; count++) result *= base; return result; } console.log(power(4)); // → 16 console.log(power(4, 3)); // → 64

Στο επόμενο κεφάλαιο, θα δούμε πώς το σώμα μιας συνάρτησης μπορεί να σας πει τον ακριβή αριθμό των ορισμάτων που μεταβιβάζονται σε αυτήν. Αυτό είναι χρήσιμο γιατί σας επιτρέπει να δημιουργήσετε μια συνάρτηση που λαμβάνει οποιοδήποτε αριθμό ορισμάτων. Για παράδειγμα, το console.log χρησιμοποιεί αυτήν την ιδιότητα και εκτυπώνει όλα τα ορίσματα που μεταβιβάζονται σε αυτό:

Console.log("R", 2, "D", 2); // → R 2 D 2

Κλείσιμο

Η δυνατότητα χρήσης κλήσεων συναρτήσεων ως μεταβλητών, σε συνδυασμό με το γεγονός ότι οι τοπικές μεταβλητές αναδημιουργούνται κάθε φορά που καλείται μια συνάρτηση, μας φέρνει σε ένα ενδιαφέρον σημείο. Τι συμβαίνει με τις τοπικές μεταβλητές όταν μια συνάρτηση αποτυγχάνει;

Το ακόλουθο παράδειγμα επεξηγεί αυτό το ζήτημα. Δηλώνει τη συνάρτηση wrapValue, η οποία δημιουργεί μια τοπική μεταβλητή. Στη συνέχεια, επιστρέφει μια συνάρτηση που διαβάζει αυτήν την τοπική μεταβλητή και επιστρέφει την τιμή της.

Συνάρτηση wrapValue(n) ( var localVariable = n; return function() ( return localVariable; ); ) var wrap1 = wrapValue(1); var wrap2 = wrapValue(2); αρχείο καταγραφής κονσόλας(wrap1()); // → 1 console.log(wrap2()); // → 2

Αυτό ισχύει και λειτουργεί όπως θα έπρεπε - η πρόσβαση στη μεταβλητή παραμένει. Επιπλέον, πολλαπλές εμφανίσεις της ίδιας μεταβλητής μπορούν να υπάρχουν ταυτόχρονα, επιβεβαιώνοντας περαιτέρω το γεγονός ότι οι τοπικές μεταβλητές δημιουργούνται εκ νέου με κάθε κλήση συνάρτησης.

Αυτή η ικανότητα εργασίας με αναφορά σε κάποιο παράδειγμα μιας τοπικής μεταβλητής ονομάζεται κλείσιμο. Μια συνάρτηση που κλείνει τοπικές μεταβλητές ονομάζεται συνάρτηση κλεισίματος. Όχι μόνο σας απαλλάσσει από το να ανησυχείτε για μεταβλητούς χρόνους ζωής, αλλά σας επιτρέπει επίσης να χρησιμοποιείτε τις λειτουργίες δημιουργικά.

Με μια μικρή αλλαγή μετατρέπουμε το παράδειγμά μας σε συνάρτηση που πολλαπλασιάζει αριθμούς με οποιονδήποτε αριθμό.

Πολλαπλασιαστής συνάρτησης (συντελεστής) ( συνάρτηση επιστροφής (αριθμός) ( αριθμός επιστροφής * παράγοντας; ) var double = πολλαπλασιαστής (2); console.log(twice(5)); // → 10

Μια ξεχωριστή μεταβλητή όπως η localVariable από το παράδειγμα wrapValue δεν χρειάζεται πλέον. Δεδομένου ότι η παράμετρος είναι η ίδια μια τοπική μεταβλητή.

Χρειάζεται εξάσκηση για να αρχίσεις να σκέφτεσαι έτσι. Μια καλή εκδοχή του νοητικού μοντέλου είναι να φανταστείτε ότι η συνάρτηση παγώνει τον κώδικα στο σώμα της και τον τυλίγει σε ένα πακέτο. Όταν βλέπετε τη συνάρτηση επιστροφής(...) (...), σκεφτείτε την ως πίνακα ελέγχου για ένα κομμάτι κώδικα που έχει παγώσει για χρήση αργότερα.

Στο παράδειγμά μας, ο πολλαπλασιαστής επιστρέφει ένα παγωμένο κομμάτι κώδικα που αποθηκεύουμε στη μεταβλητή δύο φορές. Η τελευταία γραμμή καλεί τη συνάρτηση που περιέχεται στη μεταβλητή, η οποία ενεργοποιεί τον αποθηκευμένο κωδικό (αριθμός επιστροφής * παράγοντας;). Εξακολουθεί να έχει πρόσβαση στη μεταβλητή παράγοντα που ορίστηκε όταν κλήθηκε ο πολλαπλασιαστής, και έχει επίσης πρόσβαση στο όρισμα που διαβιβάστηκε κατά την απαγόρευση (5) ως αριθμητική παράμετρος.

αναδρομή

Μια συνάρτηση μπορεί κάλλιστα να καλέσει τον εαυτό της αν φροντίσει να μην ξεχειλίσει η στοίβα. Μια τέτοια συνάρτηση ονομάζεται αναδρομική. Ακολουθεί ένα παράδειγμα μιας εναλλακτικής υλοποίησης εκθέσεως:

Συνάρτηση ισχύς(βάση, εκθέτης) ( if (εκθέτης == 0) επιστρέφει 1; αλλιώς επιστροφή βάσης * power(βάση, εκθέτης - 1); ) console.log(power(2, 3)); // → 8

Έτσι ορίζουν οι μαθηματικοί την εκθετικότητα, και ίσως αυτό να περιγράφει την έννοια πιο κομψά από έναν κύκλο. Η συνάρτηση καλεί τον εαυτό της πολλές φορές με διαφορετικά ορίσματα για να επιτύχει πολλαπλασιασμό.

Ωστόσο, αυτή η υλοποίηση έχει ένα πρόβλημα - σε ένα κανονικό περιβάλλον JavaScript, είναι 10 φορές πιο αργή από την έκδοση με βρόχο. Το Looping είναι φθηνότερο από την κλήση μιας συνάρτησης.

Το δίλημμα ταχύτητα έναντι κομψότητας είναι αρκετά ενδιαφέρον. Υπάρχει ένα ορισμένο χάσμα μεταξύ της ανθρώπινης ευκολίας και της ευκολίας της μηχανής. Οποιοδήποτε πρόγραμμα μπορεί να επιταχυνθεί κάνοντας το μεγαλύτερο και πιο περίπλοκο. Ο προγραμματιστής καλείται να βρει τη σωστή ισορροπία.

Στην περίπτωση της πρώτης εκθέσεως, ο άκομψος βρόχος είναι αρκετά απλός και ξεκάθαρος. Δεν έχει νόημα να το αντικαταστήσουμε με αναδρομή. Συχνά, ωστόσο, τα προγράμματα λειτουργούν με τόσο περίπλοκες έννοιες που κάποιος θέλει να μειώσει την αποτελεσματικότητα αυξάνοντας την αναγνωσιμότητα.

Ο βασικός κανόνας, που έχει επαναληφθεί πολλές φορές, και με τον οποίο συμφωνώ απόλυτα - μην ανησυχείτε για την απόδοση μέχρι να βεβαιωθείτε ότι το πρόγραμμα επιβραδύνεται. Αν ναι, βρείτε τα ανταλλακτικά που διαρκούν περισσότερο και ανταλλάξτε εκεί την κομψότητα για αποτελεσματικότητα.

Φυσικά, δεν πρέπει να αγνοήσουμε εντελώς την απόδοση αμέσως. Σε πολλές περιπτώσεις, όπως και με την εκθέτηση, δεν έχουμε μεγάλη απλότητα από κομψές λύσεις. Μερικές φορές ένας έμπειρος προγραμματιστής βλέπει αμέσως ότι μια απλή προσέγγιση δεν θα είναι ποτέ αρκετά γρήγορη.

Το αναφέρω αυτό γιατί πάρα πολλοί αρχάριοι προγραμματιστές προσκολλώνται στην αποτελεσματικότητα ακόμη και σε μικρά πράγματα. Το αποτέλεσμα είναι μεγαλύτερο, πιο περίπλοκο και συχνά όχι χωρίς σφάλματα. Τέτοια προγράμματα χρειάζονται περισσότερο χρόνο για να γραφτούν και συχνά δεν λειτουργούν πολύ πιο γρήγορα.

Αλλά η αναδρομή δεν είναι πάντα απλώς μια λιγότερο αποτελεσματική εναλλακτική λύση για τους βρόχους. Ορισμένα προβλήματα επιλύονται ευκολότερα με την αναδρομή. Τις περισσότερες φορές, αυτή είναι μια διέλευση πολλών κλαδιών δέντρων, καθένα από τα οποία μπορεί να διακλαδωθεί.

Εδώ είναι ένας γρίφος για εσάς: μπορείτε να πάρετε έναν άπειρο αριθμό αριθμών, ξεκινώντας από τον αριθμό 1, και στη συνέχεια είτε προσθέτοντας 5 είτε πολλαπλασιάζοντας με 3. Πώς γράφουμε μια συνάρτηση που, δίνοντας έναν αριθμό, προσπαθεί να βρει μια ακολουθία τέτοιων προσθέσεις και πολλαπλασιασμοί που οδηγούν σε έναν δεδομένο αριθμό; Για παράδειγμα, ο αριθμός 13 μπορεί να ληφθεί πολλαπλασιάζοντας πρώτα το 1 επί 3 και μετά προσθέτοντας το 5 δύο φορές. Και ο αριθμός 15 είναι γενικά αδύνατο να γίνει έτσι.

Αναδρομική λύση:

Συνάρτηση findSolution(target) ( συνάρτηση find(start, history) ( if (start == target) return history; other if (start > target) return null; else return find(start + 5, "(" + history + " + 5)") || find(start * 3, "(" + history + " * 3)"); ) return find(1, "1"); ) console.log(findSolution(24)); // → (((1 * 3) + 5) * 3)

Αυτό το παράδειγμα δεν βρίσκει απαραίτητα τη συντομότερη λύση - ικανοποιεί οποιαδήποτε. Δεν περιμένω να καταλάβετε αμέσως πώς λειτουργεί το πρόγραμμα. Αλλά ας πάμε στο κάτω μέρος αυτής της σπουδαίας άσκησης στην αναδρομική σκέψη.

Η εύρεση της εσωτερικής συνάρτησης είναι αναδρομική. Χρειάζονται δύο ορίσματα - τον τρέχοντα αριθμό και μια συμβολοσειρά που περιέχει μια εγγραφή για το πώς φτάσαμε σε αυτόν τον αριθμό. Και επιστρέφει είτε μια συμβολοσειρά που δείχνει τη σειρά των βημάτων μας, είτε μηδενική.

Για να γίνει αυτό, η συνάρτηση εκτελεί μία από τις τρεις ενέργειες. Εάν ο δεδομένος αριθμός είναι ίσος με τον στόχο, τότε η τρέχουσα ιστορία είναι απλώς ο τρόπος για να το πετύχετε, γι' αυτό και επιστρέφεται. Εάν ο δεδομένος αριθμός είναι μεγαλύτερος από τον στόχο, δεν έχει νόημα να συνεχίσουμε τον πολλαπλασιασμό και την πρόσθεση, γιατί με αυτόν τον τρόπο μόνο θα αυξηθεί. Και αν δεν έχουμε φτάσει ακόμα στον στόχο, η συνάρτηση δοκιμάζει και τα δύο πιθανά μονοπάτια ξεκινώντας από τον δεδομένο αριθμό. Καλεί τον εαυτό της δύο φορές, μία με κάθε έναν από τους τρόπους. Εάν η πρώτη κλήση δεν επιστρέψει μηδενική, επιστρέφει. Διαφορετικά, το δεύτερο επιστρέφεται.

Για να κατανοήσουμε καλύτερα πώς η συνάρτηση επιτυγχάνει το επιθυμητό αποτέλεσμα, ας δούμε τις κλήσεις της που πραγματοποιούνται σε αναζήτηση λύσης για τον αριθμό 13.

Find(1, "1") find(6, "(1 + 5)") find(11, "((1 + 5) + 5)") find(16, "((1 + 5) + 5 ) + 5)") πολύ μεγάλο εύρημα(33, "((1 + 5) + 5) * 3)") πολύ μεγάλο εύρημα(18, "((1 + 5) * 3)") πολύ μεγάλο εύρημα( 3, "(1 * 3)") find(8, "((1 * 3) + 5)") find(13, "(((1 * 3) + 5) + 5)") βρέθηκε!

Η εσοχή δείχνει το βάθος της στοίβας κλήσεων. Την πρώτη φορά που η συνάρτηση εύρεσης καλείται δύο φορές για να ελέγξει τις λύσεις που ξεκινούν με (1 + 5) και (1 * 3). Η πρώτη κλήση αναζητά μια λύση που ξεκινά με (1 + 5) και χρησιμοποιεί αναδρομή για να ελέγξει όλες τις λύσεις που δίνουν έναν αριθμό μικρότερο ή ίσο με τον επιθυμητό αριθμό. Δεν το βρίσκει και επιστρέφει μηδενικό. Τότε ο χειριστής || και μεταβαίνει σε μια κλήση συνάρτησης που εξετάζει την επιλογή (1 * 3). Εδώ είμαστε τυχεροί, γιατί στην τρίτη αναδρομική κλήση παίρνουμε 13. Αυτή η κλήση επιστρέφει μια συμβολοσειρά, και κάθε ένα από τα || περνά αυτή τη συμβολοσειρά από πάνω στην πορεία, επιστρέφοντας τη λύση ως αποτέλεσμα.

Λειτουργίες ανάπτυξης

Υπάρχουν δύο λίγο πολύ φυσικοί τρόποι εισαγωγής συναρτήσεων σε ένα πρόγραμμα.

Αρχικά, γράφετε παρόμοιο κώδικα πολλές φορές. Αυτό θα πρέπει να αποφευχθεί - περισσότερος κώδικας σημαίνει περισσότερο χώρο για σφάλματα και περισσότερο υλικό ανάγνωσης για όσους προσπαθούν να κατανοήσουν το πρόγραμμα. Παίρνουμε λοιπόν επαναλαμβανόμενη λειτουργικότητα, της δίνουμε ένα καλό όνομα και τη βάζουμε σε μια συνάρτηση.

Ο δεύτερος τρόπος είναι να ανακαλύψετε την ανάγκη για κάποια νέα λειτουργικότητα που αξίζει να τοποθετηθεί σε ξεχωριστή λειτουργία. Ξεκινάτε με το όνομα της συνάρτησης και στη συνέχεια γράφετε το σώμα της. Μπορείτε ακόμη να ξεκινήσετε γράφοντας τον κώδικα που χρησιμοποιεί τη συνάρτηση πριν οριστεί η ίδια η συνάρτηση.

Το πόσο δύσκολο είναι για εσάς να ονομάσετε μια συνάρτηση δείχνει πόσο καλά κατανοείτε τη λειτουργικότητά της. Ας πάρουμε ένα παράδειγμα. Πρέπει να γράψουμε ένα πρόγραμμα που να εκτυπώνει δύο αριθμούς, τον αριθμό των αγελάδων και των κοτόπουλων στο αγρόκτημα, ακολουθούμενο από τις λέξεις "αγελάδες" και "κοτόπουλα". Πρέπει να προσθέσετε μηδενικά στους αριθμούς μπροστά, έτσι ώστε ο καθένας να καταλαμβάνει ακριβώς τρεις θέσεις.

007 Αγελάδες 011 Κότες

Προφανώς, χρειαζόμαστε μια συνάρτηση με δύο ορίσματα. Ας ξεκινήσουμε την κωδικοποίηση.
// printFarmInventory συνάρτηση printFarmInventory(αγελάδες, κοτόπουλα) ( var cowString = String(cows); while (cowString.length< 3) cowString = "0" + cowString; console.log(cowString + " Коров"); var chickenString = String(chickens); while (chickenString.length < 3) chickenString = "0" + chickenString; console.log(chickenString + " Куриц"); } printFarmInventory(7, 11);

Αν προσθέσουμε .length σε μια χορδή, παίρνουμε το μήκος της. Αποδεικνύεται ότι οι βρόχοι while προσθέτουν αρχικά μηδενικά στους αριθμούς μέχρι να λάβουν μια συμβολοσειρά 3 χαρακτήρων.

Ετοιμος! Αλλά μόλις πρόκειται να στείλουμε τον κωδικό στον αγρότη (μαζί με έναν βαρύ έλεγχο, φυσικά), τηλεφωνεί και μας λέει ότι έχει γουρούνια στη φάρμα και θα μπορούσαμε να προσθέσουμε την παραγωγή του αριθμού των γουρουνιών στο πρόγραμμα;

Φυσικά και είναι δυνατό. Αλλά όταν αρχίζουμε να αντιγράφουμε και να επικολλάμε τον κώδικα από αυτές τις τέσσερις γραμμές, συνειδητοποιούμε ότι πρέπει να σταματήσουμε και να σκεφτούμε. Πρέπει να υπάρχει καλύτερος τρόπος. Προσπαθούμε να βελτιώσουμε το πρόγραμμα:

// outputZeroPaddedWithLabel συνάρτηση printZeroPaddedWithLabel(αριθμός, ετικέτα) ( var numberString = String(number); while (numberString.length< 3) numberString = "0" + numberString; console.log(numberString + " " + label); } // вывестиИнвентаризациюФермы function printFarmInventory(cows, chickens, pigs) { printZeroPaddedWithLabel(cows, "Коров"); printZeroPaddedWithLabel(chickens, "Куриц"); printZeroPaddedWithLabel(pigs, "Свиней"); } printFarmInventory(7, 11, 3);

Εργα! Αλλά το όνομα printZeroPaddedWithLabel είναι λίγο περίεργο. Συνδυάζει τρία πράγματα - έξοδο, μηδενική συμπλήρωση και ετικέτα - σε μία λειτουργία. Αντί να γεμίσουμε ολόκληρο το επαναλαμβανόμενο κομμάτι σε μια συνάρτηση, ας επισημάνουμε μια έννοια:

// προσθήκη της συνάρτησης Zeros zeroPad(αριθμός, πλάτος) ( var string = String(number); while (string.length< width) string = "0" + string; return string; } // вывестиИнвентаризациюФермы function printFarmInventory(cows, chickens, pigs) { console.log(zeroPad(cows, 3) + " Коров"); console.log(zeroPad(chickens, 3) + " Куриц"); console.log(zeroPad(pigs, 3) + " Свиней"); } printFarmInventory(7, 16, 3);

Μια συνάρτηση με ωραίο, περιγραφικό όνομα zeroPad κάνει τον κώδικα πιο κατανοητό. Και μπορεί να χρησιμοποιηθεί σε πολλές περιπτώσεις, όχι μόνο στην περίπτωσή μας. Για παράδειγμα, για εμφάνιση μορφοποιημένων πινάκων με αριθμούς.

Πόσο έξυπνες και ευέλικτες πρέπει να είναι οι λειτουργίες; Μπορούμε να γράψουμε μια απλή συνάρτηση που συμπληρώνει έναν αριθμό με μηδενικά έως τρεις θέσεις, καθώς και μια φανταχτερή συνάρτηση γενικής χρήσης για τη μορφοποίηση αριθμών που υποστηρίζει κλάσματα, αρνητικούς αριθμούς, στοίχιση κουκκίδων, συμπλήρωση με διαφορετικούς χαρακτήρες κ.λπ.

Ένας καλός εμπειρικός κανόνας είναι να προσθέσετε μόνο τη λειτουργικότητα που χρειάζεστε οπωσδήποτε. Μερικές φορές είναι δελεαστικό να δημιουργήσετε πλαίσια γενικού σκοπού για κάθε μικρή ανάγκη. Αντισταθείτε του. Δεν θα ολοκληρώσετε ποτέ τη δουλειά, αλλά απλώς γράψτε ένα μάτσο κώδικα που κανείς δεν θα χρησιμοποιήσει.

Λειτουργίες και Παρενέργειες

Οι λειτουργίες μπορούν να χωριστούν χονδρικά σε αυτές που καλούνται λόγω των παρενεργειών τους και σε αυτές που καλούνται να αποκτήσουν κάποια αξία. Φυσικά, είναι επίσης δυνατό να συνδυαστούν αυτές οι ιδιότητες σε μία λειτουργία.

Η πρώτη βοηθητική συνάρτηση στο παράδειγμα του αγροκτήματος, printZeroPaddedWithLabel, καλείται λόγω της παρενέργειας της εκτύπωσης μιας συμβολοσειράς. Το δεύτερο, zeroPad, λόγω της τιμής επιστροφής. Και δεν είναι τυχαίο ότι το δεύτερο χαρακτηριστικό είναι πιο χρήσιμο από το πρώτο. Λειτουργίες που επιστρέφουν τιμές είναι πιο εύκολο να συνδυαστούν μεταξύ τους παρά λειτουργίες που δημιουργούν παρενέργειες.

Μια καθαρή συνάρτηση είναι ένα ειδικό είδος συνάρτησης που επιστρέφει αξία που όχι μόνο δεν έχει παρενέργειες, αλλά ούτε εξαρτάται από τις παρενέργειες του υπόλοιπου κώδικα - για παράδειγμα, δεν λειτουργεί με καθολικές μεταβλητές που μπορούν να αλλάξουν κατά λάθος κάπου αλλού. Μια καθαρή συνάρτηση, όταν καλείται με τα ίδια ορίσματα, επιστρέφει το ίδιο αποτέλεσμα (και δεν κάνει τίποτα άλλο) - κάτι που είναι πολύ ωραίο. Είναι εύκολο να συνεργαστείς μαζί της. Η κλήση μιας τέτοιας συνάρτησης μπορεί να αντικατασταθεί διανοητικά από το αποτέλεσμα της εργασίας της, χωρίς να αλλάξει η έννοια του κώδικα. Όταν θέλετε να δοκιμάσετε μια τέτοια λειτουργία, μπορείτε απλά να την καλέσετε και να είστε σίγουροι ότι εάν λειτουργεί σε αυτό το πλαίσιο, θα λειτουργήσει σε οποιαδήποτε. Οι όχι και τόσο καθαρές λειτουργίες μπορούν να αποδώσουν διαφορετικά αποτελέσματα ανάλογα με πολλούς παράγοντες και να έχουν παρενέργειες που είναι δύσκολο να δοκιμαστούν και να ληφθούν υπόψη.

Ωστόσο, δεν πρέπει να ντρέπεται κανείς να γράφει συναρτήσεις που δεν είναι αρκετά καθαρές ή να ξεκινά μια ιερή εκκαθάριση του κώδικα από τέτοιες λειτουργίες. Οι παρενέργειες είναι συχνά χρήσιμες. Δεν υπάρχει τρόπος να γράψετε μια καθαρή έκδοση της συνάρτησης console.log και αυτή η λειτουργία είναι αρκετά χρήσιμη. Ορισμένες επεμβάσεις εκφράζονται ευκολότερα χρησιμοποιώντας παρενέργειες.

Αποτέλεσμα

Αυτό το κεφάλαιο σάς έδειξε πώς να γράψετε τις δικές σας συναρτήσεις. Όταν η λέξη-κλειδί συνάρτησης χρησιμοποιείται ως έκφραση, επιστρέφει έναν δείκτη στην κλήση συνάρτησης. Όταν χρησιμοποιείται ως δήλωση, μπορείτε να δηλώσετε μια μεταβλητή εκχωρώντας μια κλήση συνάρτησης σε αυτήν.

Το κλειδί για την κατανόηση των λειτουργιών είναι τα τοπικά πεδία. Οι παράμετροι και οι μεταβλητές που δηλώνονται μέσα σε μια συνάρτηση είναι τοπικές σε αυτήν, αναδημιουργούνται κάθε φορά που καλείται και δεν είναι ορατές από έξω. Οι συναρτήσεις που δηλώνονται μέσα σε μια άλλη συνάρτηση έχουν πρόσβαση στο εύρος της.

Είναι πολύ χρήσιμο να χωρίσετε τις διάφορες εργασίες που εκτελούνται από το πρόγραμμα σε συναρτήσεις. Δεν χρειάζεται να επαναλαμβάνεστε, οι συναρτήσεις κάνουν τον κώδικα πιο ευανάγνωστο διαχωρίζοντάς τον σε σημασιολογικά μέρη, με τον ίδιο τρόπο που τα κεφάλαια και τα τμήματα ενός βιβλίου βοηθούν στην οργάνωση του απλού κειμένου.

Γυμνάσια

Ελάχιστο
Στο προηγούμενο κεφάλαιο αναφέρθηκε η συνάρτηση Math.min, η οποία επιστρέφει το μικρότερο από τα ορίσματά της. Τώρα μπορούμε να γράψουμε μόνοι μας μια τέτοια συνάρτηση. Γράφω λειτουργία min A που παίρνει δύο ορίσματα και επιστρέφει το μικρότερο από αυτά.

Console.log(min(0, 10)); // → 0 console.log(min(0, -10)); // → -10

αναδρομή
Είδαμε ότι ο τελεστής % (υπόλοιπο) μπορεί να χρησιμοποιηθεί για να προσδιοριστεί εάν ένας αριθμός είναι ζυγός (% 2). Εδώ είναι ένας άλλος τρόπος προσδιορισμού:

Το μηδέν είναι άρτιο.
Η μονάδα είναι περίεργη.
Οποιοσδήποτε αριθμός N έχει την ίδια ισοτιμία με τον N-2.

Γράψτε μια αναδρομική συνάρτηση isEven σύμφωνα με αυτούς τους κανόνες. Πρέπει να πάρει έναν αριθμό και να επιστρέψει μια τιμή boolean.

Δοκιμάστε το στα 50 και 75. Δοκιμάστε να του δώσετε -1. Γιατί συμπεριφέρεται έτσι; Είναι δυνατόν να διορθωθεί με κάποιο τρόπο;

Δοκιμάστε το στο 50 και το 75. Δείτε πώς συμπεριφέρεται στο -1. Γιατί; Μπορείςσκεφτείτε τρόπο να το διορθώσετε αυτό;

Console.log(isEven(50)); // → true console.log(isEven(75)); // → false console.log(isEven(-1)); // → ??

Μετράμε φασόλια.

Ο αριθμός χαρακτήρων N μιας συμβολοσειράς μπορεί να ληφθεί προσθέτοντας .charAt(N)("string".charAt(5)) σε αυτήν, με παρόμοιο τρόπο με τη λήψη του μήκους μιας συμβολοσειράς με .length. Η επιστρεφόμενη τιμή θα είναι μια συμβολοσειρά χαρακτήρων (για παράδειγμα, "k"). Ο πρώτος χαρακτήρας της συμβολοσειράς έχει θέση 0, που σημαίνει ότι τελευταίος χαρακτήραςΗ θέση θα είναι string.length - 1. Με άλλα λόγια, μια συμβολοσειρά δύο χαρακτήρων θα έχει μήκος 2 και οι θέσεις χαρακτήρων της θα είναι 0 και 1.

Γράψτε μια συνάρτηση countBs που παίρνει μια συμβολοσειρά ως όρισμα και επιστρέφει τον αριθμό των χαρακτήρων "B" στη συμβολοσειρά.

Στη συνέχεια, γράψτε μια συνάρτηση countChar που λειτουργεί λίγο σαν countBs, εκτός από το ότι χρειάζεται μια δεύτερη παράμετρος, τον χαρακτήρα που θα αναζητήσουμε στη συμβολοσειρά (αντί απλώς να μετράμε τον αριθμό των χαρακτήρων "B"). Για να το κάνετε αυτό, ξαναγράψτε τη συνάρτηση countBs.

Δηλώσεις μετάβασης και χειρισμός εξαιρέσεων

Μια άλλη κατηγορία τελεστών γλώσσας JavaScript είναι οι τελεστές άλματος. Όπως υποδηλώνει το όνομα, αυτές οι δηλώσεις αναγκάζουν τον διερμηνέα JavaScript να μεταβεί σε διαφορετική θέση στον κώδικα του προγράμματος. Η εντολή break αναγκάζει τον διερμηνέα να μεταβεί στο τέλος ενός βρόχου ή άλλης πρότασης. Η δήλωση συνέχειας αναγκάζει τον διερμηνέα να παρακάμψει το υπόλοιπο σώμα του βρόχου, να μεταπηδήσει πίσω στην αρχή του βρόχου και να ξεκινήσει μια νέα επανάληψη. Η JavaScript έχει τη δυνατότητα να προσθέτει ετικέτες σε δηλώσεις με ονόματα, έτσι ώστε οι εντολές break και συνέχεια να μπορούν να δηλώνονται ρητά σε ποιο βρόχο ή άλλη δήλωση ανήκουν.

Η δήλωση return αναγκάζει τον διερμηνέα να μεταπηδήσει από την καλούμενη συνάρτηση πίσω στο σημείο στο οποίο κλήθηκε και να επιστρέψει την τιμή της κλήσης. Η εντολή ρίχνει μια εξαίρεση και έχει σχεδιαστεί για να λειτουργεί σε συνδυασμό με προτάσεις try/catch/finally που ορίζουν ένα μπλοκ κώδικα για τη διαχείριση της εξαίρεσης. Αυτό είναι ένα αρκετά περίπλοκο είδος εντολών μετάβασης: όταν συμβαίνει μια εξαίρεση, ο διερμηνέας μεταβαίνει στον πλησιέστερο χειριστή εξαίρεσης που περικλείει, ο οποίος μπορεί να βρίσκεται στην ίδια συνάρτηση ή υψηλότερη, στη στοίβα επιστροφής της καλούμενης συνάρτησης.

Κάθε ένας από αυτούς τους τελεστές άλματος περιγράφεται με περισσότερες λεπτομέρειες στις ακόλουθες υποενότητες.

Ετικέτες οδηγιών

Οποιαδήποτε δήλωση μπορεί να επισημανθεί με ένα αναγνωριστικό και μια άνω και κάτω τελεία πριν από αυτήν:

αναγνωριστικό: οδηγία

Όταν προσθέτετε ετικέτα σε μια εντολή, της δίνετε ένα όνομα που μπορεί στη συνέχεια να χρησιμοποιηθεί ως αναφορά οπουδήποτε στο πρόγραμμα. Μπορείτε να επισημάνετε οποιαδήποτε εντολή, αλλά είναι λογικό να επισημαίνετε μόνο εντολές που έχουν σώμα, όπως βρόχους και εντολές υπό όρους.

Δίνοντας ένα όνομα στον βρόχο, μπορεί στη συνέχεια να χρησιμοποιηθεί σε εντολές διακοπής και συνέχειας, εντός του βρόχου για έξοδο από αυτόν ή για μετάβαση στην αρχή του βρόχου, στην επόμενη επανάληψη. Οι εντολές break και συνέχεια είναι οι μόνες δηλώσεις στη γλώσσα JavaScript που μπορούν να περιέχουν ετικέτες—θα συζητηθούν με περισσότερες λεπτομέρειες αργότερα. Το παρακάτω είναι ένα παράδειγμα μιας δήλωσης while με μια ετικέτα και μιας δήλωσης συνέχειας που χρησιμοποιεί αυτήν την ετικέτα:

Mainloop: while (token != null) ( // Ο κωδικός προγράμματος παραλείφθηκε... συνέχεια mainloop; // Μετάβαση στην επόμενη επανάληψη του ονομαζόμενου βρόχου )

Το αναγνωριστικό που χρησιμοποιείται ως ετικέτα δήλωσης μπορεί να είναι οποιοδήποτε έγκυρο αναγνωριστικό JavaScript, εκτός από μια δεσμευμένη λέξη. Τα ονόματα των ετικετών είναι ξεχωριστά από τα ονόματα μεταβλητών και συναρτήσεων, επομένως μπορείτε να χρησιμοποιήσετε αναγνωριστικά που ταιριάζουν με ονόματα μεταβλητών ή συναρτήσεων ως ετικέτες.

Οι ετικέτες οδηγιών ορίζονται μόνο μέσα στις οδηγίες στις οποίες ισχύουν (και, φυσικά, μέσα στις οδηγίες που βρίσκονται μέσα σε αυτές). Οι ένθετες εντολές δεν μπορούν να επισημανθούν με τα ίδια αναγνωριστικά με τις οδηγίες που περιέχουν, αλλά δύο ανεξάρτητες εντολές μπορούν να επισημανθούν με την ίδια ετικέτα. Οι οδηγίες με ετικέτα μπορούν να επισημανθούν εκ νέου. Δηλαδή, οποιαδήποτε εντολή μπορεί να έχει πολλαπλές ετικέτες.

δήλωση διακοπής

Η εντολή break προκαλεί την άμεση έξοδο από τον πιο εσωτερικό βρόχο ή την εντολή διακόπτη. Έχουμε ήδη δει παραδείγματα χρήσης μιας εντολής break μέσα σε μια εντολή switch νωρίτερα. Στους βρόχους, χρησιμοποιείται συνήθως για άμεση έξοδο από τον βρόχο όταν, για κάποιο λόγο, είναι απαραίτητο να τερματιστεί η εκτέλεση του βρόχου.

Όταν ο κύκλος είναι πολύ σύνθετη κατάστασηολοκλήρωση, είναι συχνά πιο εύκολο να εφαρμοστούν αυτές οι συνθήκες με μια εντολή break παρά να προσπαθήσουμε να τις εκφράσουμε σε έναν μόνο βρόχο υπό όρους. Το παρακάτω παράδειγμα προσπαθεί να βρει ένα στοιχείο πίνακα με μια συγκεκριμένη τιμή. Ο βρόχος τελειώνει με τον συνήθη τρόπο όταν φτάσει στο τέλος του πίνακα ή με την εντολή break, μόλις βρεθεί η επιθυμητή τιμή:

Var arr = ["a","b","c","d","e"], αποτέλεσμα; για (var i = 0; i

Στο JavaScript, μπορείτε να καθορίσετε το όνομα της ετικέτας μετά τη λέξη-κλειδί break (ένα αναγνωριστικό χωρίς άνω και κάτω τελεία):

break label_name;

Όταν η εντολή break χρησιμοποιείται με μια ετικέτα, μεταβαίνει στο τέλος της ονομαζόμενης πρότασης ή τερματίζει την εκτέλεσή της. Ελλείψει εντολής με την καθορισμένη ετικέτα, μια προσπάθεια χρήσης αυτής της φόρμας της εντολής break δημιουργεί ένα συντακτικό σφάλμα. Μια πρόταση με όνομα δεν χρειάζεται να είναι ένας βρόχος ή μια εντολή διακόπτη. Η δήλωση διακοπής με ετικέτα μπορεί να "ξεφύγει" από οποιαδήποτε δήλωση περιέχει. Μια συνημμένη δήλωση μπορεί να είναι ακόμη και ένα απλό μπλοκ εντολών που περικλείεται σε σγουρές αγκύλες με μοναδικό σκοπό τη σήμανση.

Δεν μπορεί να εισαχθεί χαρακτήρας νέας γραμμής μεταξύ της λέξης-κλειδιού αλλαγής και του ονόματος της ετικέτας. Αυτό συμβαίνει επειδή ο διερμηνέας JavaScript εισάγει αυτόματα ερωτηματικά που λείπουν: εάν σπάσετε μια γραμμή κώδικα μεταξύ της λέξης-κλειδιού break και της ετικέτας που την ακολουθεί, ο διερμηνέας θα υποθέσει ότι εννοούσατε την απλή μορφή αυτού του τελεστή χωρίς ετικέτα και προσθέσει ένα ερωτηματικό .

Η δήλωση διακοπής με ετικέτα απαιτείται μόνο όταν θέλετε να διακόψετε την εκτέλεση μιας πρότασης που δεν είναι ο πλησιέστερος βρόχος ή εντολή διακόπτη.

συνέχεια δήλωσης

Η δήλωση συνέχειας είναι παρόμοια με την εντολή break. Ωστόσο, αντί να βγείτε από τον βρόχο, η εντολή συνέχεια ξεκινά μια νέα επανάληψη του βρόχου. Η σύνταξη για τη δήλωση συνέχειας είναι τόσο απλή όσο η σύνταξη για την εντολή break. Η δήλωση συνέχειας μπορεί επίσης να χρησιμοποιηθεί με ετικέτα.

Η δήλωση συνέχειας, είτε χωρίς ετικέτα είτε με ετικέτα, μπορεί να χρησιμοποιηθεί μόνο εντός του σώματος ενός βρόχου. Η χρήση του οπουδήποτε αλλού έχει ως αποτέλεσμα ένα συντακτικό σφάλμα. Όταν εκτελείται μια εντολή συνέχειας, η τρέχουσα επανάληψη του βρόχου διακόπτεται και ξεκινά η επόμενη. Για ΔΙΑΦΟΡΕΤΙΚΟΙ ΤΥΠΟΙκύκλοι σημαίνει διαφορετικά πράγματα:

    Στον βρόχο while, η έκφραση που καθορίζεται στην αρχή του βρόχου ελέγχεται ξανά και εάν είναι αληθής, το σώμα του βρόχου εκτελείται από την αρχή.

    Ο βρόχος do/while μεταβαίνει στο τέλος του βρόχου, όπου η συνθήκη ελέγχεται ξανά πριν επαναληφθεί ο βρόχος.

    Στον βρόχο for, η έκφραση προσαύξησης αξιολογείται και η δοκιμαστική έκφραση αξιολογείται ξανά για να καθοριστεί εάν θα πρέπει να πραγματοποιηθεί η επόμενη επανάληψη.

    Σε έναν βρόχο for/in, ο βρόχος ξεκινά εκ νέου, εκχωρώντας στην καθορισμένη μεταβλητή το όνομα της επόμενης ιδιότητας.

Σημειώστε τη διαφορά στη συμπεριφορά της εντολής συνέχεια στους βρόχους while και for. Ο βρόχος while επιστρέφει απευθείας στην κατάστασή του, ενώ ο βρόχος for πρώτα αξιολογεί την έκφραση της αύξησης και μετά επιστρέφει στη συνθήκη. Το ακόλουθο παράδειγμα δείχνει τη χρήση μιας δήλωσης συνέχειας χωρίς ετικέτα για έξοδο από την τρέχουσα επανάληψη ενός βρόχου για ζυγούς αριθμούς:

var sum = 0; // Υπολογίστε το άθροισμα των περιττών αριθμών από 0 - 10 για (var i = 0; i

Η εντολή συνέχεια, όπως και το break, μπορεί να χρησιμοποιηθεί σε ένθετους βρόχους σε μια μορφή που περιλαμβάνει μια ετικέτα, οπότε ο βρόχος που επανεκκινείται δεν είναι απαραίτητα αυτός που περιέχει αμέσως τη δήλωση συνέχειας. Επίσης, όπως και με τη διακοπή, οι νέες γραμμές μεταξύ της λέξης-κλειδιού συνέχειας και του ονόματος της ετικέτας δεν επιτρέπονται.

δήλωση επιστροφής

Μια κλήση συνάρτησης είναι μια έκφραση, και όπως όλες οι εκφράσεις, έχει μια τιμή. Η δήλωση επιστροφής εντός συναρτήσεων χρησιμοποιείται για τον προσδιορισμό της τιμής που επιστρέφεται από τη συνάρτηση. Η εντολή return μπορεί να τοποθετηθεί μόνο στο σώμα μιας συνάρτησης. Η παρουσία του οπουδήποτε αλλού είναι συντακτικό σφάλμα. Όταν εκτελείται μια δήλωση επιστροφής, η συνάρτηση επιστρέφει την τιμή της παράστασης στο καλούν πρόγραμμα. Για παράδειγμα:

Εάν μια συνάρτηση δεν έχει εντολή επιστροφής, όταν καλείται, ο διερμηνέας θα εκτελέσει τις εντολές στο σώμα της συνάρτησης μία προς μία μέχρι να φτάσει στο τέλος της συνάρτησης και μετά θα επιστρέψει τον έλεγχο στο πρόγραμμα που την κάλεσε. Σε αυτήν την περίπτωση, η έκφραση κλήσης θα επιστρέψει απροσδιόριστη. Η δήλωση επιστροφής είναι συχνά τελευταία οδηγίασε μια συνάρτηση, αλλά αυτό είναι εντελώς προαιρετικό: η συνάρτηση θα επιστρέψει τον έλεγχο στο καλούν πρόγραμμα μόλις επιτευχθεί η εντολή επιστροφής, ακόμα κι αν ακολουθείται από άλλες εντολές στο σώμα της συνάρτησης.

Η δήλωση επιστροφής μπορεί επίσης να χρησιμοποιηθεί χωρίς έκφραση, οπότε απλώς ακυρώνει τη συνάρτηση και επιστρέφει απροσδιόριστο στον καλούντα. Για παράδειγμα:

Συνάρτηση myFun(arr) ( // Εάν ο πίνακας περιέχει αρνητικούς αριθμούς, ακυρώστε τη συνάρτηση για (var i = 0; i

ρίξει δήλωση

Εξαίρεσηείναι ένα σήμα που υποδεικνύει την εμφάνιση κάποιου είδους εξαίρεσης ή σφάλματος. Αύξηση εξαίρεσης (ρίψη)είναι ένας τρόπος για να επισημάνετε ένα τέτοιο σφάλμα ή εξαίρεση. To catch a exception (catch) σημαίνει να το χειρίζεσαι, δηλ. να λάβει τα απαραίτητα ή κατάλληλα μέτρα για την ανάκαμψη από την εξαίρεση.

Στο JavaScript, δημιουργούνται εξαιρέσεις όταν παρουσιάζεται σφάλμα χρόνου εκτέλεσης και όταν το πρόγραμμα το ανεβάζει ρητά με τη δήλωση ρίψης. Οι εξαιρέσεις εντοπίζονται χρησιμοποιώντας δηλώσεις try/catch/finally, οι οποίες περιγράφονται αργότερα.

Η πρόταση ρίχνει την ακόλουθη σύνταξη:

ρίξει έκφραση?

Το αποτέλεσμα μιας έκφρασης μπορεί να είναι μια τιμή οποιουδήποτε τύπου. Η δήλωση ρίχνει μπορεί να μεταβιβαστεί ένας αριθμός που αντιπροσωπεύει τον κωδικό σφάλματος ή μια συμβολοσειρά που περιέχει το κείμενο του μηνύματος σφάλματος. Ο διερμηνέας JavaScript δημιουργεί εξαιρέσεις χρησιμοποιώντας μια παρουσία μιας κλάσης λάθοςμία από τις υποκατηγορίες του και μπορείτε επίσης να χρησιμοποιήσετε μια παρόμοια προσέγγιση. Το αντικείμενο Σφάλμα έχει μια ιδιότητα όνομα, το οποίο ορίζει τον τύπο σφάλματος και την ιδιότητα μήνυμα A που περιέχει τη συμβολοσειρά μεταβιβάστηκε στη συνάρτηση κατασκευαστή. Το παρακάτω είναι ένα παράδειγμα συνάρτησης που δημιουργεί ένα αντικείμενο Σφάλμα όταν καλείται με μη έγκυρο όρισμα:

// Παραγοντικό συνάρτησης μιας αριθμητικής συνάρτησης factorial(number) ( // Εάν το όρισμα εισόδου δεν είναι έγκυρη τιμή, // δημιουργείται μια εξαίρεση! if (αριθμός 1; i *= αριθμός, αριθμός--); /* κενό σώμα βρόχου */ return i ; ) κονσόλα.log("5! = ", factorial(5)); κονσόλα log("-3! = ", παραγοντικό(-3));

Όταν δημιουργείται μια εξαίρεση, ο διερμηνέας JavaScript διακόπτει αμέσως την κανονική εκτέλεση του προγράμματος και μεταβαίνει στον πλησιέστερο χειριστή εξαιρέσεων. Οι χειριστές εξαιρέσεων χρησιμοποιούν τη δήλωση catch της κατασκευής try/catch/finally, η οποία περιγράφεται στην επόμενη ενότητα.

Εάν το μπλοκ κώδικα στο οποίο προέκυψε η εξαίρεση δεν έχει μια αντίστοιχη κατασκευή catch, ο διερμηνέας αναλύει το επόμενο εξωτερικό μπλοκ κώδικα και ελέγχει για να δει εάν ένας χειριστής εξαίρεσης σχετίζεται με αυτό. Αυτό συνεχίζεται μέχρι να βρεθεί ο χειριστής.

Εάν μια εξαίρεση τεθεί σε μια συνάρτηση που δεν περιέχει μια κατασκευή try/catch/finally για να την χειριστεί, τότε η εξαίρεση διαδίδεται στον κώδικα που κάλεσε τη συνάρτηση. Αυτός είναι ο τρόπος με τον οποίο οι εξαιρέσεις διαδίδονται μέσω της λεξιλογικής δομής των μεθόδων JavaScript στη στοίβα κλήσεων. Εάν δεν βρεθεί ποτέ ένας χειριστής εξαίρεσης, η εξαίρεση αντιμετωπίζεται ως σφάλμα και αναφέρεται στον χρήστη.

δοκιμάσω/πιάω/τελικά κατασκευάζω

Η κατασκευή try/catch/finally υλοποιεί τον μηχανισμό χειρισμού εξαιρέσεων της JavaScript. δοκιμή δήλωσηςσε αυτήν την κατασκευή απλώς ορίζει ένα μπλοκ κώδικα στο οποίο χειρίζονται εξαιρέσεις. Το μπλοκ δοκιμής ακολουθείται από δήλωση αλιευμάτωνμε ένα μπλοκ εντολών που πρέπει να καλείται εάν παρουσιαστεί εξαίρεση οπουδήποτε στο μπλοκ δοκιμής. Η δήλωση catch ακολουθείται από ένα μπλοκ τελικά A που περιέχει κώδικα που εκτελεί τις τελικές λειτουργίες και είναι εγγυημένο ότι θα εκτελεστεί ανεξάρτητα από το τι συμβαίνει στο μπλοκ δοκιμής.

Τόσο το μπλοκ catch όσο και το τελικό μπλοκ είναι προαιρετικά, αλλά τουλάχιστον ένα από αυτά πρέπει να υπάρχει μετά το μπλοκ δοκιμής. δοκιμάστε, πιάστε και τελικά μπλοκ ξεκινούν και τελειώνουν άγκιστρα. Αυτό είναι υποχρεωτικό μέρος της σύνταξης και δεν μπορεί να παραλειφθεί ακόμη και αν υπάρχει μόνο μία δήλωση μεταξύ τους.

Το ακόλουθο απόσπασμα απεικονίζει τη σύνταξη και τον σκοπό της κατασκευής try/catch/finally:

Δοκιμάστε ( // Κανονικά, αυτός ο κώδικας θα εκτελείται ομαλά από την αρχή μέχρι το τέλος. // Αλλά σε κάποιο σημείο, μπορεί να δημιουργήσει μια εξαίρεση, // είτε απευθείας με τη δήλωση ρίψης, είτε έμμεσα, // καλώντας τη μέθοδο που εκτελεί το εξαίρεση. ) catch (ex) ( // Οι εντολές σε αυτό το μπλοκ εκτελούνται εάν και μόνο εάν υπάρχει εξαίρεση στο μπλοκ try //. Αυτές οι δηλώσεις μπορούν να χρησιμοποιήσουν μια τοπική μεταβλητή ex που // αναφέρεται στο αντικείμενο Σφάλμα ή σε άλλη τιμή που καθορίζεται στη δήλωση ρίψης. // Αυτό το μπλοκ μπορεί είτε να χειριστεί την εξαίρεση με κάποιο τρόπο, είτε // να την αγνοήσει και να κάνει κάτι άλλο ή // να επαναφέρει την εξαίρεση με μια δήλωση ρίχνοντας. ) τέλος ( // Αυτό το μπλοκ περιέχει δηλώσεις που εκτελούνται πάντα, ανεξάρτητα από το αν , // τι συνέβη στο μπλοκ δοκιμής Εκτελούνται εάν το μπλοκ δοκιμής τελείωσε: // 1) ως συνήθως, φτάνοντας στο τέλος του μπλοκ // 2) λόγω διακοπής, συνέχειας ή επιστροφής δηλώσεις // 3) με εξαίρεση που χειρίζεται στο μπλοκ αλίευσης παραπάνω // 4) με μια εξαίρεση που δεν έχει εντοπιστεί που συνεχίζει // να διαδίδεται σε υψηλότερα επίπεδα)

Σημειώστε ότι η λέξη-κλειδί catch ακολουθείται από ένα αναγνωριστικό σε παρένθεση. Αυτό το αναγνωριστικό είναι παρόμοιο με μια παράμετρο συνάρτησης. Όταν συλλαμβάνεται μια εξαίρεση, αυτή η παράμετρος θα οριστεί σε μια εξαίρεση (για παράδειγμα, ένα αντικείμενο Σφάλμα). Σε αντίθεση με μια κανονική μεταβλητή, το αναγνωριστικό που σχετίζεται με μια δήλωση catch υπάρχει μόνο στο σώμα του μπλοκ catch.

Το παρακάτω είναι ένα πιο ρεαλιστικό παράδειγμα κατασκευής try/catch. Καλεί τη μέθοδο factorial() που ορίστηκε στο προηγούμενο παράδειγμα και τις μεθόδους prompt() και alert() της JavaScript από την πλευρά του πελάτη για να οργανώσει την είσοδο και την έξοδο:

Δοκιμάστε ( // Ζητήστε από τον χρήστη έναν αριθμό var n = Number(prompt("Εισαγάγετε έναν θετικό αριθμό", "")); // Υπολογίστε το παραγοντικό ενός αριθμού, υποθέτοντας // η είσοδος είναι έγκυρη var f = factorial( n); // Εκτύπωση της ειδοποίησης αποτελέσματος(n + "! = " + f); ) catch (ex) ( // Εάν τα δεδομένα είναι λανθασμένα, ο έλεγχος θα μεταφερθεί εδώ alert(ex); // Ειδοποίηση του χρήστη σχετικά με το λάθος )

Εάν ο χρήστης εισάγει αρνητικό αριθμό, θα εμφανιστεί ένα προειδοποιητικό μήνυμα:

Αυτό είναι ένα παράδειγμα κατασκευής try/catch χωρίς πρόταση τελικού. Αν και τελικά δεν χρησιμοποιείται τόσο συχνά όσο τα αλιεύματα, εντούτοις μερικές φορές είναι χρήσιμο. Το τελικό μπλοκ είναι εγγυημένο ότι θα εκτελεστεί εάν τουλάχιστον κάποιο μέρος του μπλοκ δοκιμής έχει εκτελεστεί, ανεξάρτητα από το πώς τελείωσε ο κώδικας στο μπλοκ δοκιμής. Αυτή η δυνατότητα χρησιμοποιείται συνήθως για την εκτέλεση τελικών λειτουργιών μετά την εκτέλεση του κώδικα σε μια συνέχεια δοκιμής.

Σε μια κανονική κατάσταση, ο έλεγχος φτάνει στο τέλος του μπλοκ δοκιμής και μετά μεταβαίνει στο τελικό μπλοκ, το οποίο εκτελεί τις απαραίτητες τελικές λειτουργίες. Εάν ο έλεγχος εξέλθει από ένα μπλοκ δοκιμής ως αποτέλεσμα μιας δήλωσης επιστροφής, συνέχειας ή διακοπής, το τελικό μπλοκ εκτελείται πριν μεταφερθεί ο έλεγχος αλλού.

Εάν παρουσιαστεί μια εξαίρεση σε ένα μπλοκ δοκιμής και υπάρχει ένα κατάλληλο μπλοκ catch για να το χειριστείτε, ο έλεγχος μεταφέρεται πρώτα στο μπλοκ catch και μετά στο τελικό μπλοκ. Εάν δεν υπάρχει τοπικό μπλοκ σύλληψης, τότε ο έλεγχος περνά πρώτα στο τελικό μπλοκ και μετά μεταβαίνει στο πλησιέστερο εξωτερικό μπλοκ αλίευσης που μπορεί να χειριστεί την εξαίρεση.

Εάν το ίδιο το τελικό μπλοκ μεταφέρει τον έλεγχο χρησιμοποιώντας μια δήλωση επιστροφής, συνέχειας, διακοπής ή ρίψης ή καλώντας μια μέθοδο που δημιουργεί μια εξαίρεση, η εντολή μεταφοράς σε εκκρεμότητα ακυρώνεται και εκτελείται μια νέα. Για παράδειγμα, εάν το τελικό μπλοκ εισάγει μια εξαίρεση, αυτή η εξαίρεση θα αντικαταστήσει οποιαδήποτε εξαίρεση που είχε τεθεί προηγουμένως.

Χειριστής ΕΠΙΣΤΡΟΦΗτερματίζει την τρέχουσα συνάρτηση και επιστρέφει την τιμή της.

Ο πηγαίος κώδικας για αυτό το διαδραστικό παράδειγμα αποθηκεύεται σε ένα αποθετήριο GitHub. Εάν θέλετε να συνεισφέρετε στο έργο διαδραστικών παραδειγμάτων, κλωνοποιήστε τη διεύθυνση https://github.com/mdn/interactive-examples

Σύνταξη

επιστροφή [[έκφραση]]; έκφραση Η έκφραση της οποίας η τιμή θα επιστραφεί. Εάν δεν προσδιορίζεται, επιστρέφεται το undefined.

Περιγραφή

Όταν μια εντολή επιστροφής καλείται σε μια συνάρτηση, η εκτέλεσή της σταματά. Η καθορισμένη τιμή επιστρέφεται στο μέρος όπου κλήθηκε η συνάρτηση. Για παράδειγμα, η ακόλουθη συνάρτηση επιστρέφει την τετραγωνική τιμή του ορίσματός της, x (όπου x είναι ένας αριθμός):

συνάρτηση square(x) ( return x * x; ) var demo = square(3); // η τιμή επίδειξης θα είναι 9

Εάν δεν έχει καθοριστεί τιμή επιστροφής, επιστρέφεται το undefined.

Οι παρακάτω εκφράσεις τερματίζουν πάντα την εκτέλεση μιας συνάρτησης:

ΕΠΙΣΤΡΟΦΗ; επιστροφή αληθινή? επιστροφή ψευδής? επιστροφή x; επιστροφή x + y / 3;

Αυτόματα ερωτηματικά

συνάρτηση magic(x) ( συνάρτηση επιστροφής calc(x) ( return x * 42 ); ) var answer = magic(); answer(1337); // 56154

Προδιαγραφές

Προσδιορισμός Κατάσταση Ενα σχόλιο
ECMAScript 1st Edition (ECMA-262) Πρότυπο αρχικός ορισμός
ECMAScript 5.1 (ECMA-262)
Πρότυπο
ECMAScript 2015 (6η Έκδοση, ECMA-262)
Ορισμός της "Δήλωση επιστροφής" σε αυτήν την προδιαγραφή.
Πρότυπο
Τελευταίο προσχέδιο ECMAScript (ECMA-262)
Ορισμός της "Δήλωση επιστροφής" σε αυτήν την προδιαγραφή.
Προσχέδιο

Συμβατότητα προγράμματος περιήγησης

Ο πίνακας συμβατότητας σε αυτήν τη σελίδα δημιουργείται από δομημένα δεδομένα. Εάν θέλετε να συνεισφέρετε στα δεδομένα, ελέγξτε τα από το https://github.com/mdn/browser-compat-data αποθετήριο και στείλτε μας ένα αίτημα έλξης για τις αλλαγές σας.

Ενημερώστε τα δεδομένα συμβατότητας στο GitHub

ΥπολογιστέςΚινητόυπηρέτης
ΧρώμιοάκρηFirefoxInternet ExplorerΛΥΡΙΚΗ ΣΚΗΝΗσαφάριAndroid webviewChrome για AndroidFirefox για AndroidOpera για AndroidSafari σε iOSSamsung InternetNode.js
ΕΠΙΣΤΡΟΦΗΧρώμιο Πλήρης υποστήριξη 1 άκρη Πλήρης υποστήριξη 12 Firefox Πλήρης υποστήριξη 1 ΔΗΛ Πλήρης υποστήριξη 3 ΛΥΡΙΚΗ ΣΚΗΝΗ Πλήρης υποστήριξηΝαίσαφάρι Πλήρης υποστήριξηΝαίwebview android Πλήρης υποστήριξη 1 Chrome Android Πλήρης υποστήριξη 18 Firefox Android Πλήρης υποστήριξη 4 OperaAndroid Πλήρης υποστήριξηΝαίSafari iOS Πλήρης υποστήριξηΝαίSamsung Internet Android Πλήρης υποστήριξη 1.0 nodejs Πλήρης υποστήριξηΝαί

Οι συναρτήσεις είναι ένα από τα πιο σημαντικά δομικά στοιχεία κώδικα στο JavaScript.

Οι συναρτήσεις αποτελούνται από ένα σύνολο εντολών και συνήθως εκτελούν μια συγκεκριμένη εργασία (για παράδειγμα, άθροιση αριθμών, υπολογισμός ρίζας κ.λπ.).

Ο κώδικας που τοποθετείται σε μια συνάρτηση θα εκτελεστεί μόνο μετά τη ρητή κλήση σε αυτήν τη συνάρτηση.

Δήλωση λειτουργίας

1.Σύνταξη:

//Συνάρτηση δήλωσης συνάρτησης FunctionName(var1, var2)( Κωδικός συνάρτησης ) //Κλήση συνάρτησης FunctionName(var1,var2);

2. Σύνταξη:

//Δήλωση συνάρτησης var functionname=function(var1, var2)(Κωδικός συνάρτησης) //Όνομα συνάρτησης κλήσης συνάρτησης(var1,var2);

όνομα συνάρτησηςκαθορίζει το όνομα της συνάρτησης. Κάθε συνάρτηση στη σελίδα πρέπει να έχει ένα μοναδικό όνομα. Πρέπει να δοθεί το όνομα της συνάρτησης με λατινικά γράμματακαι δεν πρέπει να ξεκινάει με αριθμούς.

ανά 1Και ανά 2είναι μεταβλητές ή τιμές που μπορούν να περάσουν μέσα σε μια συνάρτηση. Ένας απεριόριστος αριθμός μεταβλητών μπορεί να περάσει σε κάθε συνάρτηση.

Σημείωση:ακόμα κι αν δεν περάσουν μεταβλητές στη συνάρτηση, μην ξεχάσετε να εισαγάγετε παρενθέσεις "()" μετά το όνομα της συνάρτησης.

Σημείωση:Τα ονόματα συναρτήσεων στο JavaScript κάνουν διάκριση πεζών-κεφαλαίων.

Παράδειγμα λειτουργίας JavaScript

Η συνάρτηση messageWrite() στο παρακάτω παράδειγμα θα εκτελεστεί μόνο αφού κάνετε κλικ στο κουμπί.

Σημείωση:αυτό το παράδειγμα χρησιμοποιεί το συμβάν onclick. Τα συμβάντα JavaScript θα καλυφθούν λεπτομερώς αργότερα σε αυτό το σεμινάριο.



Μεταβίβαση μεταβλητών σε συναρτήσεις

Μπορείτε να μεταβιβάσετε απεριόριστο αριθμό μεταβλητών σε συναρτήσεις.

Σημείωση:Όλοι οι χειρισμοί σε μεταβλητές μέσα στις συναρτήσεις εκτελούνται στην πραγματικότητα όχι στις ίδιες τις μεταβλητές, αλλά στο αντίγραφό τους, επομένως τα περιεχόμενα των ίδιων των μεταβλητών δεν αλλάζουν ως αποτέλεσμα της εκτέλεσης των συναρτήσεων.

/* Ορίστε μια συνάρτηση που προσθέτει 10 στη μεταβλητή που πέρασε και εξάγει το αποτέλεσμα στη σελίδα */ συνάρτηση συν(a)( a=a+10; document.write("Έξοδος συνάρτησης: " + a+"
"); ) var a=25; document.write("Τιμή μεταβλητής πριν από την κλήση συνάρτησης: "+a+"
"); // Καλέστε τη συνάρτηση που της μεταβιβάζει τη μεταβλητή a plus(a); document.write("Η τιμή της μεταβλητής μετά την κλήση της συνάρτησης: "+a+"
");

Γρήγορη ματιά

Για να αποκτήσετε πρόσβαση σε μια καθολική μεταβλητή από μια συνάρτηση αντί από ένα αντίγραφό της, χρησιμοποιήστε window.variable_name.

Συνάρτηση plus(a)( window.a=a+10; ) var a=25; document.write("Τιμή μεταβλητής πριν από την κλήση συνάρτησης: "+a+"
"); plus(a); document.write("Μεταβλητή τιμή μετά την κλήση συνάρτησης: "+a+"
");

Γρήγορη ματιά

εντολή επιστροφής

Με την εντολή ΕΠΙΣΤΡΟΦΗΜπορείτε να επιστρέψετε τιμές από συναρτήσεις.



Γρήγορη ματιά

Ενσωματωμένες Λειτουργίες

Εκτός από τις λειτουργίες που καθορίζονται από το χρήστη στο JavaScript, υπάρχουν επίσης ενσωματωμένες λειτουργίες.

Για παράδειγμα, η ενσωματωμένη λειτουργία είναι πεπερασμένοσας επιτρέπει να ελέγξετε εάν η τιμή που περάσατε είναι έγκυρος αριθμός.

Document.write(isFinite(40)+"
"); document.write(isFinite(-590)+"
"); document.write(isFinite(90.33)+"
"); document.write(isFinite(NaN)+"
"); document.write(isFinite("Αυτή είναι μια συμβολοσειρά")+"
");

Γρήγορη ματιά

Σημείωση: πλήρης λίσταενσωματωμένες λειτουργίες JavaScript που μπορείτε να βρείτε στο .

Τοπικές και καθολικές μεταβλητές

Οι μεταβλητές που δημιουργούνται μέσα στις συναρτήσεις καλούνται τοπικές μεταβλητές. Μπορείτε να έχετε πρόσβαση σε τέτοιες μεταβλητές μόνο μέσα στις συναρτήσεις στις οποίες έχουν οριστεί.

Μετά την εκτέλεση του κώδικα συνάρτησης, τέτοιες μεταβλητές καταστρέφονται. Αυτό σημαίνει ότι οι μεταβλητές με το ίδιο όνομα μπορούν να οριστούν σε διαφορετικές συναρτήσεις.

Οι μεταβλητές που δημιουργούνται εκτός του κώδικα συνάρτησης καλούνται καθολικές μεταβλητέςΑυτές οι μεταβλητές είναι προσβάσιμες από οπουδήποτε στον κώδικα.

Εάν δηλώσετε μια μεταβλητή χωρίς var μέσα σε μια συνάρτηση, γίνεται επίσης καθολική.

Οι καθολικές μεταβλητές καταστρέφονται μόνο όταν η σελίδα είναι κλειστή.



Γρήγορη ματιά

Σημείωση:όταν εμφανίζεται, το var2 θα είναι null επειδή το func1 λειτουργεί στην τοπική "έκδοση" του var2.

Χρήση ανώνυμων συναρτήσεων

Οι συναρτήσεις που δεν περιέχουν όνομα όταν δηλώνονται καλούνται Ανώνυμος.

Οι ανώνυμες συναρτήσεις βασικά δηλώνονται όχι για την επακόλουθη κλήση τους από τον κώδικα ως συνηθισμένες συναρτήσεις, αλλά για μετάβαση σε άλλες συναρτήσεις ως παράμετρος.

Συνάρτηση arrMap(arr,func)( var res=new Array; for (var i=0;i ");

Γρήγορη ματιά

Κάντο μόνος σου

Ασκηση 1. Διορθώστε τα σφάλματα στον παρακάτω κώδικα:

Ασκηση 1

Διορθώστε το σφάλμα στον κώδικα.



Εργασία 2.

  1. Αναπαράγετε τον κωδικό των συναρτήσεων 1-3 εξετάζοντας τη συμπεριφορά τους όταν περνούν διαφορετικές παραμέτρους.
  2. Προσδιορίστε τη λέξη-κλειδί αλληλεπιδρώντας με τη συνάρτηση 4.

Εργασία 2

//Κλήση της πρώτης μυστικής συνάρτησης document.write(secfunc1(4,12) + "
"); // Κλήση της δεύτερης μυστικής συνάρτησης document.write(secfunc2(100,10) + "
"); //Κλήση της τρίτης μυστικής συνάρτησης secfunc3(23,10); document.write("
"); // Κλήση της τέταρτης μυστικής συνάρτησης secfunc4("n");

Ενεργοποιήστε την JavaScript για να χρησιμοποιήσετε το σύστημα σχολίων Disqus.




Μπλουζα