Λειτουργίες JavaScript. Εκφραστική 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("Shit!"); ); κάνουν θόρυβο(); // → Khrya! 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(); console.log(x); // → εξωτερικό var f2 = function() ( x = "inside f2"; ); f2(); console.log(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()); // → ___/""""\______/"\_

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

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

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

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

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

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

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

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

Var launchMissiles = συνάρτηση(τιμή) (missileSystem.launch("ή!"); ); if (safeMode) launchMissiles = function(value) (/* cancel */);

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

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

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

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

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

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

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

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

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

Λειτουργία greet(who) ( console.log("Hello, " + 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); console.log(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 φορές πιο αργή από την έκδοση με βρόχο. Το περπάτημα μέσω ενός βρόχου είναι φθηνότερο από το να καλέσετε μια συνάρτηση.

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

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

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

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

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

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

Εδώ είναι ένας γρίφος: μπορείτε να πάρετε έναν άπειρο αριθμό αριθμών ξεκινώντας από τον αριθμό 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 Κοτόπουλα

Προφανώς, χρειαζόμαστε μια συνάρτηση με δύο ορίσματα. Ας ξεκινήσουμε την κωδικοποίηση.
// εκτύπωση συνάρτηση FarmInventory 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 σε μια χορδή, παίρνουμε το μήκος της. Τελικά φαίνεται πως ενώ βρόχουςπροσθέστε αρχικά μηδενικά σε αριθμούς μέχρι να λάβετε μια συμβολοσειρά 3 χαρακτήρων.

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

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

// έξοδος ΜΕ Προσθήκη Μηδενικών ΚΑΙ Ετικετών συνάρτηση printZeroPaddedWithLabel(number, label) ( 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 είναι λίγο περίεργο. Συνδυάζει τρία πράγματα—έξοδο, προσθήκη μηδενικών και ετικέτα—σε μία συνάρτηση. Αντί να εισάγουμε ένα ολόκληρο επαναλαμβανόμενο κομμάτι σε μια συνάρτηση, ας επισημάνουμε μια έννοια:

// προσθήκη μηδενικής συνάρτησης 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 και αυτή η λειτουργία είναι αρκετά χρήσιμη. Ορισμένες επεμβάσεις εκφράζονται ευκολότερα χρησιμοποιώντας παρενέργειες.

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

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

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

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

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

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

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

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

Δοκιμάστε το στα 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.

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

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

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

1. Σύνταξη:

//Δήλωση της συνάρτησης functionFunctionname(ln1, ln2)( Κωδικός συνάρτησης) //Κλήση της συνάρτησηςFunctionname(ln1,lr2);

2. Σύνταξη:

//Δήλωση της συνάρτησης var όνομα συνάρτησης=συνάρτηση(ln1, ln2)(Κωδικός συνάρτησης) //Κλήση ονόματος συνάρτησης(ln1,lr2);

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

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

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

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

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

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

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

// Η συνάρτηση γράφει κείμενο στη συνάρτηση σελίδας messageWrite() ( document.write("Αυτό το κείμενο γράφτηκε στη σελίδα χρησιμοποιώντας 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+"
");

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

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

Με την εντολή return μπορείτε να επιστρέψετε τιμές από συναρτήσεις.

//Η συνάρτηση sum επιστρέφει το άθροισμα των μεταβλητών που της μεταβιβάστηκαν συνάρτηση sum(v1,v2)( return v1+v2; ) document.write("5+6=" + sum(5,6) + "
"); document.write("10+4=" + sum(10,4) + "
");

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

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

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

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

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

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

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

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

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

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

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

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

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

//Δήλωση καθολικών μεταβλητών var1 και var2 var var1="var1 υπάρχει"; var var2; συνάρτηση func1() ( //Εκχώρηση var2 μιας τιμής μέσα στη συνάρτηση func1 var var2="var2 υπάρχει"; ) //Από μια άλλη συνάρτηση, εκτυπώστε τα περιεχόμενα της μεταβλητής var1 και var2 στη συνάρτηση σελίδας func2() ( //Print τα περιεχόμενα της μεταβλητής var1 document.write( var1 + "
"); //Εξαγωγή των περιεχομένων της μεταβλητής var2 document.write(var2); )

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

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

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

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

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

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