Ultimate Οδηγός για Getters και Setters στο JavaScript
Getters και ρυθμιστές χρησιμοποιούνται λειτουργίες ή μέθοδοι παίρνω και σειρά τις τιμές των μεταβλητών. Η ιδέα του getter-setter είναι κοινές στον προγραμματισμό των υπολογιστών: σχεδόν όλες οι γλώσσες προγραμματισμού υψηλού επιπέδου έρχονται με ένα σύνολο συνταγών για την υλοποίηση getters και setters, συμπεριλαμβανομένου του JavaScipt.
Σε αυτήν την ανάρτηση, θα δούμε ποιοι είναι οι ρυθμιστές getters και πώς να να τα δημιουργήσετε και να τα χρησιμοποιήσετε στο JavaScript.
Getters-setters και encapsulation
Η ιδέα των getters και setters αναφέρεται πάντα σε συνδυασμό με την ενθυλάκωση. Ενθυλάκωση μπορεί να είναι κατανοητό με δύο τρόπους.
Πρώτον, είναι η δημιουργία του δεδομένα-getters-setters τρίο για πρόσβαση και τροποποίηση αυτών των δεδομένων. Αυτός ο ορισμός είναι χρήσιμος όταν πρέπει να χρησιμοποιηθούν ορισμένες λειτουργίες, όπως η επικύρωση τα δεδομένα πριν από την αποθήκευση ή την προβολή του-getters και ρυθμιστές παρέχουν το τέλειο σπίτι για αυτό.
Δεύτερον, υπάρχει ένας αυστηρότερος ορισμός σύμφωνα με τον οποίο γίνεται η ενθυλάκωση απόκρυψη δεδομένων, για να μην είναι δυνατή η πρόσβαση από άλλο κώδικα, εκτός από τους getters και τους setters. Με αυτόν τον τρόπο δεν καταλήγουμε τυχαία αντικατάσταση σημαντικών δεδομένων με κάποιο άλλο κωδικό στο πρόγραμμα.
Δημιουργήστε getters και setters
1. Με μεθόδους
Από τους getters και τους setters βασικά λειτουργίες που φέρνουν / αλλάζουν μια τιμή, υπάρχουν περισσότερο από έναν τρόπο για τη δημιουργία και τη χρήση τους. Ο πρώτος τρόπος είναι:
var obj = foo: 'αυτή είναι η τιμή του foo', getFoo: function () return this.foo; , setFoo: συνάρτηση (val) this.foo = val; κονσόλα.log (obj.getFoo ()); // "αυτή είναι η τιμή του foo" obj.setFoo ('hello'); console.log (obj.getFoo ()); // "γεια σας"
Αυτό είναι τον απλούστερο τρόπο να δημιουργήσουν getters και setters. Υπάρχει ιδιοκτησία foo
και υπάρχουν δύο μέθοδοι: getFoo
και setFoo
προς το επιστρέψτε και ορίστε μια τιμή σε αυτή την ιδιοκτησία.
2. Με τις λέξεις-κλειδιά
Περισσότερα “επίσημος” και ισχυρός τρόπος δημιουργίας getters και setters είναι χρησιμοποιώντας το παίρνω
και σειρά
λέξεις-κλειδιά.
Προς το δημιουργήστε ένα getter, Τοποθετήστε το παίρνω
λέξη-κλειδί μπροστά από μια δήλωση λειτουργίας που θα χρησιμεύσει ως μέθοδος getter και θα χρησιμοποιήσει το σειρά
λέξη-κλειδί με τον ίδιο τρόπο δημιουργήστε έναν ρυθμιστή. Η σύνταξη είναι η εξής:
var obj = fooVal: 'αυτή είναι η τιμή του foo', get foo () return this.fooVal; , ορίστε foo (val) this.fooVal = val; κονσόλα.log (obj.foo); // "αυτή είναι η τιμή του foo" obj.foo = 'hello'; console.log (obj.foo); // "γεια σας"
Σημειώστε ότι τα δεδομένα μπορούν να είναι μόνο αποθηκεύονται κάτω από ένα όνομα ιδιοκτησίας (fooVal
) διαφορετικός από το όνομα των μεθόδων getter-setter (foo
) επειδή μια ιδιοκτησία που κατέχει το getter-setter δεν μπορεί να κρατήσει τα δεδομένα επισης.
Ποιος είναι ο καλύτερος τρόπος?
Αν επιλέξετε να δημιουργήσετε getters και setters με λέξεις-κλειδιά, μπορείτε να χρησιμοποιήσετε το για να ορίσετε τα δεδομένα και το dot operator για να πάρει τα δεδομένα, με τον ίδιο τρόπο που έχετε πρόσβαση / ορίζετε την τιμή μιας κανονικής ιδιότητας.
Ωστόσο, αν επιλέξετε τον πρώτο τρόπο κωδικοποίησης των getters και των ρυθμιστών, πρέπει να καλέσετε τις μεθόδους setter και getter χρησιμοποιώντας τη σύνταξη κλήσης λειτουργίας επειδή είναι τυπικές λειτουργίες (τίποτα ξεχωριστό, όπως αυτά που δημιουργούνται χρησιμοποιώντας το παίρνω
και σειρά
λέξεις-κλειδιά).
Επίσης, υπάρχει πιθανότητα να καταλήξετε τυχαία αποδίδοντας κάποια άλλη αξία στις ιδιότητες που διέθεταν αυτές τις μεθόδους getter-setter και τα χάσετε εντελώς! Κάτι που δεν χρειάζεται να ανησυχείτε με τη μετέπειτα μέθοδο.
Έτσι, μπορείτε να δείτε γιατί είπα το η δεύτερη τεχνική είναι πιο ισχυρή.
Αντικατάσταση της πρόληψης
Εάν για κάποιο λόγο προτιμάτε την πρώτη τεχνική, κάντε τις ιδιότητες που κρατούν τις μεθόδους του getter-setter μόνο για ανάγνωση δημιουργώντας τους χρησιμοποιώντας Object.defineProperties
. Οι ιδιότητες δημιουργήθηκαν μέσω Object.defineProperties
, Object.defineProperty
και Reflect.defineProperty
να ρυθμίσετε αυτόματα προς το εγγράψιμο: ψευδές
που σημαίνει μόνο για ανάγνωση:
/ * Προστασία αντικατάστασης * / var obj = foo: 'αυτή είναι η τιμή foo'; Αντικείμενο.defineProperties (obj, 'getFoo': value: function () return this.foo;, 'setFoo': value: function (val) this.foo = val;); obj.getFoo = 66; // getFoo δεν πρόκειται να αντικατασταθεί! console.log (obj.getFoo ()); // "αυτή είναι η τιμή του foo"
Δραστηριότητες μέσα σε getters και setters
Μόλις εισαγάγετε τους getters και τους setters, μπορείτε να προχωρήσετε και εκτελέστε εργασίες στα δεδομένα πριν αλλάξετε ή επιστρέψετε.
Στον παρακάτω κώδικα, στη λειτουργία getter τα δεδομένα είναι σε συνδυασμό με μια συμβολοσειρά πριν από την επιστροφή, και στη λειτουργία setter επικύρωση της αν η τιμή είναι ένας αριθμός ή όχι εκτελείται πριν από την ενημέρωση n
.
var obj = n: 67, get id () επιστροφή 'Το αναγνωριστικό είναι:' + this.n; , ορίστε id (val) if (typeof val === 'αριθμός') this.n = val; κονσόλα.log (obj.id); // Το αναγνωριστικό είναι: 67 "obj.id = 893; console.log (obj.id); // Το αναγνωριστικό είναι: 893 "obj.id = 'hello'; console.log (obj.id); // "Το αναγνωριστικό είναι: 893"
Προστατεύστε τα δεδομένα με getters και setters
Μέχρι τώρα, καλύψαμε τη χρήση των getters και των ρυθμιστών στο πρώτο πλαίσιο της εγκαψούλωσης. Ας προχωρήσουμε στο δεύτερο, δηλαδή πώς να απόκρυψη δεδομένων από εξωτερικό κώδικα με τη βοήθεια των getters και των ρυθμιστών.
Μη προστατευμένα δεδομένα
Η εγκατάσταση των getters και των ρυθμιστών δεν σημαίνει ότι τα δεδομένα μπορούν να προσπελαστούν και να τροποποιηθούν μόνο μέσω αυτών των μεθόδων. Στο ακόλουθο παράδειγμα, είναι άλλαξε άμεσα χωρίς να αγγίζετε τις μεθόδους getter και setter:
var obj = fooVal: 'αυτή είναι η τιμή του foo', get foo () return this.fooVal; , ορίστε foo (val) this.fooVal = val; obj.fooVal = 'γεια'; console.log (obj.foo); // "γεια σας"
Δεν χρησιμοποιήσαμε τον ρυθμιστή αλλά άλλαξε άμεσα τα δεδομένα (fooVal
). Τα δεδομένα που αρχικά ρυθμίσαμε μέσα obj
έχει φύγει τώρα! Για να μην συμβεί αυτό (τυχαία), εσείς χρειάζονται κάποια προστασία για τα δεδομένα σας. Μπορείτε να προσθέσετε αυτό με περιορίζοντας το πεδίο εφαρμογής όπου είναι διαθέσιμα τα δεδομένα σας. Μπορείτε να το κάνετε και από τις δύο block scoping ή εύρους λειτουργίας.
1. Αποκλεισμός πεδίων εφαρμογής
Ένας τρόπος είναι να χρησιμοποιήστε ένα πεδίο μπλοκ μέσα στο οποίο θα καθοριστούν τα δεδομένα χρησιμοποιώντας το αφήνω
λέξη-κλειδί που περιορίζει το πεδίο εφαρμογής της σε αυτό το μπλοκ.
ΕΝΑ πεδίο αποκλεισμού μπορεί να δημιουργηθεί τοποθετώντας τον κωδικό σας μέσα σε ένα ζευγάρι σγουρά τιράντες. Κάθε φορά που δημιουργείτε ένα πεδίο μπλοκ, φροντίστε να το Αφήστε ένα σχόλιο πάνω από αυτό ζητώντας τα τιράντες να μένουν μόνοι, έτσι ώστε κανείς αφαιρεί τα τιράντες λανθασμένα σκέφτονται ότι είναι μερικές πρόσθετες πλεονασμένες τιράντες στον κώδικα ή προσθέστε μια ετικέτα στο πεδίο του μπλοκ.
/ * BLOCK SCOPE, αφήστε τα τιράντες μόνο! * / let fooVal = 'αυτή είναι η τιμή του foo'; var obj = get foo () επιστροφή fooVal; , set foo (val) fooVal = val fooVal = 'γεια'; // δεν πρόκειται να επηρεάσει το fooVal μέσα στο block console.log (obj.foo); // "αυτή είναι η τιμή του foo"
Αλλαγή / δημιουργία fooVal
έξω από το μπλοκ δεν θα επηρεάσει ο fooVal
παραπομπή εντός των ρυθμιστών getters.
2. Καθορισμός πεδίων λειτουργίας
Ο συνηθέστερος τρόπος για την προστασία των δεδομένων με τον προσδιορισμό του πεδίου εφαρμογής είναι με κρατώντας τα δεδομένα μέσα σε μια λειτουργία και επιστροφή ενός αντικειμένου με τους getters και τους setters από αυτή τη λειτουργία.
λειτουργία myobj () var fooVal = 'αυτή είναι η τιμή του foo'; επιστροφή get foo () return fooVal; , set foo (val) fooVal = val fooVal = 'γεια'; // δεν πρόκειται να επηρεάσει την αρχική fooVal var obj = myobj (); console.log (obj.foo); // "αυτή είναι η τιμή του foo"
Το αντικείμενο (με το foo ()
getter-setter μέσα σε αυτό) που επιστρέφεται από το myobj ()
είναι αποθηκεύτηκαν στο obj
, και μετά obj
χρησιμοποιείται για να καλέστε τον αγοραστή και τον ρυθμιστή.
3. Προστασία δεδομένων χωρίς οριοθέτηση
Υπάρχει επίσης ένας άλλος τρόπος που μπορείτε να προστατέψετε τα δεδομένα σας από την αντικατάστασή τους χωρίς να περιορίζεται το πεδίο εφαρμογής της. Η λογική πίσω από αυτό πηγαίνει έτσι: πώς μπορείτε να αλλάξετε ένα κομμάτι δεδομένων αν δεν ξέρετε τι λέγεται?
Εάν τα δεδομένα έχουν a όχι τόσο εύκολο να αναπαραχθεί το όνομα της μεταβλητής / ιδιοκτησίας, οι πιθανότητες είναι ότι κανείς (ακόμη και οι ίδιοι) δεν θα καταλήξει να το αντικαταστήσει αναθέτοντας κάποια αξία στο όνομα της μεταβλητής / ιδιοκτησίας.
var obj = s89274934764: 'αυτή είναι η τιμή του foo', get foo () return this.s89274934764; , set foo (val) this.s89274934764 = val; κονσόλα.log (obj.foo); // "αυτή είναι η τιμή του foo"
Δείτε, αυτός είναι ένας τρόπος να δουλεύεις. Αν και το όνομα που επέλεξα δεν είναι πραγματικά καλό, μπορείτε επίσης χρησιμοποιήστε τυχαίες τιμές ή σύμβολα για να δημιουργήσετε ονόματα ιδιοκτησίας όπως προτείνεται από τον Derick Bailey σε αυτήν την ανάρτηση ιστολογίου. Ο κύριος στόχος είναι να κρατήστε τα δεδομένα κρυμμένα από άλλο κώδικα και αφήστε το ζεύγος getter-setter να έχει πρόσβαση / ενημέρωση.
Πότε θα πρέπει να χρησιμοποιείτε getters και setters?
Τώρα έρχεται το μεγάλο ερώτημα: αρχίζετε να αναθέτετε τους getters και τους setters σε όλα τα δεδομένα σας τώρα?
Αν είσαι κρύβοντας δεδομένα, τότε υπάρχει καμία άλλη επιλογή.
Αλλά αν τα δεδομένα σας φαίνονται με άλλο κώδικα είναι ωραία, πρέπει ακόμα να χρησιμοποιήσετε τους getters setters απλά για να το συνδυάσετε με κωδικό που εκτελεί κάποιες πράξεις σε αυτό; θα έλεγα Ναί. Κώδικας προσθέτει πολύ σύντομα. Δημιουργία μικρομονάδων μεμονωμένων δεδομένων με το δικό της setter σας παρέχει μια ορισμένη ανεξαρτησία να επεξεργάζεται τα εν λόγω δεδομένα χωρίς να επηρεάζει άλλα τμήματα του κώδικα.