Guida definitiva a getter e setter in JavaScript
Getters e setter sono funzioni o metodi usati per ottenere e impostato i valori delle variabili. Il concetto getter-setter è comune nella programmazione di computer: quasi tutti i linguaggi di programmazione di alto livello sono dotati di una serie di sintassi per implementare getter e setter, incluso JavaScipt.
In questo post vedremo cosa sono i setter dei getter e come creare e usarli in JavaScript.
Getter-setter e incapsulamento
L'idea di getter e setter è sempre menzionata in concomitanza con l'incapsulamento. Incapsulamento può essere inteso in due modi.
Innanzitutto, è la creazione del data-getter-setter trio per accedere e modificare tali dati. Questa definizione è utile quando alcune operazioni, come la convalida, devono essere eseguito sui dati prima di salvarlo o visualizzarlo, i getter ei setter forniscono la casa perfetta per questo.
In secondo luogo, esiste una definizione più rigorosa in base alla quale viene eseguito l'incapsulamento nascondere i dati, per renderlo inaccessibile da altro codice, tranne attraverso i getter ei setter. In questo modo non finiamo sovrascrivere accidentalmente dati importanti con qualche altro codice nel programma.
Crea getter e setter
1. Con metodi
Poiché getter e setter sono fondamentalmente funziona che recupera / cambia un valore, ci sono più di un modo per creare e usarli. Il primo modo è:
var obj = foo: 'questo è il valore di foo', getFoo: function () ritorno this.foo; , setFoo: function (val) this.foo = val; console.log (obj.getFoo ()); // "questo è il valore di foo" obj.setFoo ('hello'); console.log (obj.getFoo ()); // "Ciao"
Questo è il modo più semplice per creare getter e setter. C'è una proprietà foo
e ci sono due metodi: getFoo
e setFoo
a restituire e assegnare un valore a quella proprietà.
2. Con parole chiave
Un altro “ufficiale” e un modo efficace per creare getter e setter è utilizzare il ottenere
e impostato
parole chiave.
A creare un getter, posiziona il ottenere
parola chiave di fronte a una dichiarazione di funzione che servirà come metodo getter e utilizzare il impostato
parola chiave allo stesso modo di creare un setter. La sintassi è la seguente:
var obj = fooVal: 'questo è il valore di foo', ottenere foo () return this.fooVal; , imposta foo (val) this.fooVal = val; console.log (obj.foo); // "questo è il valore di foo" obj.foo = 'hello'; console.log (obj.foo); // "Ciao"
Si noti che i dati possono essere solo memorizzato sotto il nome di una proprietà (fooVal
) quello è diverso dal nome dei metodi getter-setter (foo
) perché una proprietà che tiene il getter-setter non può contenere i dati anche.
Qual è il modo migliore?
Se si sceglie di creare getter e setter con parole chiave, è possibile utilizzare il comando operatore di assegnazione per impostare i dati e il punto operatore per ottenere i dati, allo stesso modo in cui accederai / imposterai il valore di una proprietà normale.
Tuttavia, se si sceglie il primo modo di codificare getter e setter, è necessario chiamare i metodi setter e getter usando la sintassi di chiamata della funzione perché sono funzioni tipiche (niente di speciale come quelli creati usando il ottenere
e impostato
le chiavi).
Inoltre, c'è la possibilità che tu possa finire per caso assegnare qualche altro valore alle proprietà che hanno tenuto quei metodi getter-setter e perderli completamente! Qualcosa di cui non devi preoccuparti nel metodo successivo.
Quindi, puoi capire perché ho detto il la seconda tecnica è più robusta.
Prevenzione della sovrascrittura
Se per qualche motivo preferisci la prima tecnica, fai in modo che le proprietà mantengano i metodi getter-setter sola lettura creando loro utilizzando Object.defineProperties
. Proprietà create tramite Object.defineProperties
, Object.defineProperty
e Reflect.defineProperty
configurare automaticamente a scrivibile: falso
che significa sola lettura:
/ * Prevenzione della sovrascrittura * / var obj = pippo: 'questo è il valore di foo'; Object.defineProperties (obj, 'getFoo': valore: function () ritorno this.foo;, 'setFoo': valore: function (val) this.foo = val;); obj.getFoo = 66; // getFoo non verrà sovrascritto! console.log (obj.getFoo ()); // "questo è il valore di foo"
Operazioni all'interno di getter e setter
Una volta che hai introdotto getter e setter, puoi andare avanti e eseguire operazioni sui dati prima di cambiarlo o restituirlo.
Nel codice sottostante, nella funzione getter i dati sono concatenato con una stringa prima di essere restituito, e nella funzione setter una convalida di se il valore è un numero o meno viene eseguito prima dell'aggiornamento n
.
var obj = n: 67, get id () return 'L'ID è:' + this.n; , imposta id (val) if (typeof val === 'number') this.n = val; console.log (obj.id); // "L'ID è: 67" obj.id = 893; console.log (obj.id); // "L'ID è: 893" obj.id = 'hello'; console.log (obj.id); // "L'ID è: 893"
Proteggi i dati con getter e setter
Finora, abbiamo coperto l'uso di getter e setter nel primo contesto dell'incapsulamento. Passiamo al secondo, cioè come nascondere i dati dal codice esterno con l'aiuto di getter e setter.
Dati non protetti
L'impostazione di getter e setter non significa che i dati possano essere consultati e modificati solo tramite tali metodi. Nell'esempio seguente, lo è cambiato direttamente senza toccare i metodi getter e setter:
var obj = fooVal: 'questo è il valore di foo', ottenere foo () return this.fooVal; , imposta foo (val) this.fooVal = val; obj.fooVal = 'hello'; console.log (obj.foo); // "Ciao"
Non abbiamo usato il setter ma direttamente modificato i dati (fooVal
). I dati inizialmente impostati all'interno obj
è andato ora! Per evitare che ciò accada (accidentalmente), tu bisogno di protezione per i tuoi dati Puoi aggiungerlo tramite limitando l'ambito di dove sono disponibili i tuoi dati. Puoi farlo da entrambi scoping del blocco o scoping della funzione.
1. Ambito del blocco
Un modo è quello di usa un ambito di blocco all'interno del quale i dati saranno definiti utilizzando il permettere
parola chiave che limita il suo scopo a quel blocco.
UN ambito di blocco può essere creato inserendo il tuo codice all'interno di un paio di parentesi graffe. Ogni volta che crei un ambito di blocco, assicurati di lascia un commento sopra di esso chiedendo che le coppie siano lasciate sole, in modo che nessuno rimuove le parentesi graffe per errore pensando che siano alcune parentesi ridondanti in più nel codice o aggiungi un'etichetta allo scopo del blocco.
/ * BLOCK SCOPE, lascia le parentesi! * / let fooVal = 'questo è il valore di foo'; var obj = get foo () return fooVal; , set foo (val) fooVal = val fooVal = 'hello'; // non intaccherà il fooVal all'interno del blocco console.log (obj.foo); // "questo è il valore di foo"
Modifica / creazione fooVal
fuori dal blocco non influenzerà il fooVal
riferito all'interno del Getter Setters.
2. Scopo della funzione
Il modo più comune per proteggere i dati con l'ambito è di mantenere i dati all'interno di una funzione e restituire un oggetto con i getter e setter da quella funzione.
function myobj () var fooVal = 'questo è il valore di foo'; return get foo () return fooVal; , set foo (val) fooVal = val fooVal = 'hello'; // non influenzerà il nostro originale fooVal var obj = myobj (); console.log (obj.foo); // "questo è il valore di foo"
L'oggetto (con il foo ()
getter-setter all'interno di esso) restituito dal myObj ()
la funzione è salvato in obj
, e poi obj
è abituato a chiama il getter e setter.
3. Protezione dei dati senza ambito
C'è anche un altro modo per proteggere i tuoi dati dalla sovrascrittura senza limitarne la portata. La logica dietro è così: come puoi cambiare un dato se non sai come si chiama?
Se i dati hanno un nome della variabile / proprietà non facilmente riproducibile, è probabile che nessuno (anche noi stessi) sta per finire sovrascrivendola assegnando un valore a quel nome di variabile / proprietà.
var obj = s89274934764: 'questo è il valore di foo', ottenere foo () return this.s89274934764; , imposta foo (val) this.s89274934764 = val; console.log (obj.foo); // "questo è il valore di foo"
Vedi, questo è un modo per risolvere le cose. Anche se il nome che ho scelto non è veramente buono, puoi anche farlo usa valori o simboli casuali per creare nomi di proprietà come proposto da Derick Bailey in questo post del blog. L'obiettivo principale è quello di mantenere i dati nascosti da altro codice e lascia che una coppia getter-setter acceda / aggiorni.
Quando dovresti usare getter e setter?
Ora arriva la grande domanda: inizi ad assegnare getter e setter a tutti i tuoi dati adesso?
Se tu sei nascondere i dati, allora c'è nessuna altra scelta.
Ma se i tuoi dati sono visti da un altro codice va bene, hai ancora bisogno di usare getter setter solo per legarlo con il codice che esegue alcune operazioni su di esso? direi sì. Codice si somma molto presto. Creazione di micro unità di dati individuali con il proprio getter-setter ti fornisce una certa indipendenza lavorare su tali dati senza intaccare altre parti del codice.