Προγραμματισμός

Εκμάθηση JavaScript: Λειτουργίες υψηλότερης τάξης

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

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

Εάν γράφετε JavaScript, πιθανότατα έχετε χρησιμοποιήσει συναρτήσεις υψηλότερης τάξης και δεν έχετε παρατηρήσει καν. Εάν έχετε αντικαταστήσει ποτέ ένα Για βρόχο με μια μέθοδο πίνακα, έχετε χρησιμοποιήσει συναρτήσεις υψηλότερης τάξης. Εάν έχετε χρησιμοποιήσει ποτέ τα αποτελέσματα μιας κλήσης AJAX (χωρίς ασύγχρονος/αναμένω), έχετε χρησιμοποιήσει συναρτήσεις υψηλότερης παραγγελίας (τόσο οι υποσχέσεις όσο και οι επιστροφές κλήσεων περιλαμβάνουν λειτουργίες υψηλότερης παραγγελίας). Εάν έχετε γράψει ποτέ ένα στοιχείο React που εμφανίζει μια λίστα στοιχείων, έχετε χρησιμοποιήσει συναρτήσεις υψηλότερης τάξης. Ας δούμε αυτά τα παραδείγματα:

const item = ['a', 'b', 'c', 'd', 'e']

// Αντί για αυτό για βρόχο ....

για (let i = 0; i <items.length - 1; i ++) {

console.log (στοιχεία [i]);

}

// Μπορούμε να χρησιμοποιήσουμε το ForEach, μια λειτουργία υψηλότερης τάξης

// (forEach παίρνει μια συνάρτηση ως όρισμα)

items.forEach ((item) => console.log (item));

// Επιστροφές ή υποσχέσεις, αν κάνετε

// ασύγχρονα αιτήματα, χρησιμοποιείτε

// συναρτήσεις υψηλότερης τάξης

get ('// aws.random.cat/meow', (απάντηση) => {

putImageOnScreen (respons.file);

});

λήψη ('// random.dog/woof.json').then((response) => {

putImageOnScreen (respons.file);

});

// Στο στοιχείο React παρακάτω, χρησιμοποιείται χάρτης,

// που είναι συνάρτηση υψηλότερης τάξης

const myListComponent = (στηρίγματα) => {

ΕΠΙΣΤΡΟΦΗ (

   

    {props.items.map ((αντικείμενο) => {

    ΕΠΙΣΤΡΟΦΗ (

  • {είδος}
  • )

          })}

      );

    };

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

εξαγωγή προεπιλεγμένης σύνδεσης (mapStateToProps, mapDispatchToProps) (MyComponent);

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

const createLogger = (περιβάλλον) => {

επιστροφή (msg) => {

console.log ("$ {konteks}: $ {msg}");

  }

};

const log = createLogger ('myFile');

log («Ένα πολύ σημαντικό μήνυμα»);

// αποσυνδέεται "myFile: Ένα πολύ σημαντικό μήνυμα"

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

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

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

let protectedObject = (συνάρτηση () {

αφήστε το myVar = 0;

ΕΠΙΣΤΡΟΦΗ {

λήψη: () => myVar,

αύξηση: () => myVar ++,

  };

})();

protectedObject.get (); // επιστρέφει 0

protectedObject.increment ();

protectedObject.get (); // επιστρέφει 1

myVar = 42; // Ωχ! μόλις δημιουργήσατε μια καθολική μεταβλητή

protectedObject.get (); // εξακολουθεί να επιστρέφει 1

Ωστόσο, ας μην παρασυρθούμε. Οι λειτουργίες υψηλότερης τάξης δεν απαιτούν κάτι φανταχτερό όπως το κλείσιμο Είναι απλά συναρτήσεις που λαμβάνουν άλλες λειτουργίες ως επιχειρήματα ή που επιστρέφουν συναρτήσεις Τελεία. Αν θέλετε περισσότερα παραδείγματα ή περαιτέρω ανάγνωση, ρίξτε μια ματιά στο κεφάλαιο σχετικά με τις λειτουργίες υψηλότερης τάξης στο "Eloquent JavaScript" της Marijn Haverbeke.

Ερωτήσεις ή σχόλια; Μη διστάσετε να επικοινωνήσετε με το Twitter: @freethejazz.