2015-01-29 12 views
76

Sono confuso su quale sia il punto di getter e setter nelle classi ECMAScript 6. Qual è lo scopo? Di seguito è riportato un esempio mi riferisco a:Cosa sono i getter e i setter nelle classi ECMAScript 6?

class Employee { 

    constructor(name) { 
     this._name = name; 
    } 

    doWork() { 
     return `${this._name} is working`; 
    } 

    get name() { 
     return this._name.toUpperCase(); 
    } 

    set name(newName){ 
     if(newName){ 
      this._name = newName; 
     } 
    } 
} 
+0

È simile a quelli in C#, se vi capita di saperlo. –

+0

Correlati: [Qual è l'argomento per l'utilizzo di getter e setter ES6 rispetto alla convenzione getProperty/setProperty?] (Http://stackoverflow.com/q/32114468/1048572) – Bergi

+0

Un buon articolo che spiega proprio questo può essere trovato su: https://coryrylan.com/blog/javascript-es6-class-syntax "Nella nostra classe di sopra abbiamo un getter e setter per la nostra proprietà name Usiamo la convenzione '_' per creare un backing field per memorizzare la nostra proprietà name. questo ogni volta che get o set viene chiamato causerebbe un overflow dello stack "... Si parla anche della variabile che non è veramente 'privata', ma ci sono numerosi nuovi modi per creare private vars nelle classi JS; il mio preferito è solo usare Typescript, ma ho usato anche l'approccio Symbol – webdevinci

risposta

83

Questi setter e getter consentono di utilizzare le proprietà direttamente (senza utilizzare la parentesi)

var emp = new Employee("TruMan1"); 

if (emp.name) { 
    // uses the get method in the background 
} 

emp.name = "New name"; // uses the setter in the background 

Questo è solo per impostare e ottenere il valore della proprietà.

+1

Intendevi proprietà invece di attributi? Un po 'di confusione per me – Krizzu

+0

Good eye, @Krizzu. Gli attributi esistono in JavaScript e sono _completamente_ cose diverse dalle proprietà. La risposta fa infatti riferimento a proprietà e non attributi. Ho modificato la risposta. Non penso che il rispondente penserà. :) –

+0

Non sono sicuro che questo sia davvero un vantaggio, in qualche modo nasconde la nozione di usare setter/getter. Un cliente di una classe potrebbe pensare che usi direttamente le proprietà, dove non è appropriato, ma sono d'accordo che rispetti il ​​principio di occultamento di informazioni/dettagli. Forse se usiamo questo di conseguenza rende l'utilizzo più semplice e devo solo abituarmi ad esso più ... –

36

getter e setter in ES6 servire allo stesso scopo che lo fanno in altre lingue tra cui ... ES5. ES5 consente già getter e setter tramite Object.defineProperty, sebbene siano meno puliti e più scomodi da utilizzare.

In modo efficace, getter e setter consentono di utilizzare la notazione di accesso alle proprietà standard per letture e scritture pur avendo la possibilità di personalizzare il modo in cui la proprietà viene recuperata e mutata senza i metodi getter e setter espliciti necessari.

Nella classe Employee sopra, questo significherebbe si potrebbe accedere alla proprietà name in questo modo:

console.log(someEmployee.name); 

Sarebbe guardare come un normale accesso alle proprietà, ma sarebbe in realtà chiamare toUpperCase sul nome prima restituendolo. Allo stesso modo, facendo questo:

someEmployee.name = null; 

sarebbe accedere al setter, e non sarebbe modificare la _name proprietà interna a causa della clausola di salvaguardia introdotta nel setter name s'.

Vedere anche la domanda generale Why use getters and setters? per ulteriori informazioni sul motivo per cui è utile modificare la funzionalità di accesso dei membri.

+0

Spiegazione molto chiara. Grazie! –

0

I getter e setter ES6 hanno una motivazione sostanzialmente diversa rispetto ai concetti simili in Java.

In Java, getter e setter consentono a una classe di definire un JavaBean. Il punto di getter e setter è che consente al bean di avere un'interfaccia "completamente ortogonale" da quella implicita dai campi pubblici. Quindi posso avere un campo "nome" che NON è una proprietà JavaBean, e posso avere un "indirizzo" di proprietà JavaBean che NON è un campo.

Le proprietà JavaBean sono anche "rilevabili" da migliaia di framework (ad esempio Hibernate) tramite Java reflection. Pertanto, getter e setter fanno parte di un metodo standard per "esporre" le proprietà dei bean.

Getter e setter, essendo funzioni, hanno anche il valore che "astraggono" l'implementazione. Può essere EITHER un campo o un valore calcolato ("sintetico"). Quindi, se ho una proprietà bean chiamata "zipcode", inizia come stringa memorizzata. Ora supponiamo che voglio cambiarlo per essere un valore calcolato da indirizzo/città/stato?

Se io uso un campo, questo codice si rompe:

 String zipcode = address.zipcode(); 

Ma se io uso un getter, questo non rompere:

 String zipcode = address.getZipcode(); 

JavaScript non ha nulla di simile JavaBeans. Per quanto ho letto, il valore previsto di GET e SET è limitato alle proprietà "sintetiche" (calcolate) di cui sopra.

Ma è un po 'meglio di Java in quanto, mentre Java non consente di convertire un "campo" in modo compatibile con un metodo, ES6 GET e SET lo consentono.

Cioè, se ho:

 var zipcode = address.zipcode; 

Se cambio codice postale dall'essere una proprietà dell'oggetto standard per un getter, il codice sopra chiama ora la funzione GET.

Si noti che se non includessi GET nella definizione, questo NON richiamerebbe il metodo GET di zipcode. Invece, assegnerebbe semplicemente la funzione zipcode al var.

Quindi penso che queste siano alcune distinzioni importanti per comprendere i getter e setter di Java e JavaScript ES6.