A cosa servono getter e setter nelle classi ECMAScript 6?


102

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

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;
        }
    }
}

1
È simile a quelli in C #, se ti capita di saperlo.
Arturo Torres Sánchez


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

Risposte:


108

Questi setter e getter ti consentono di utilizzare le proprietà direttamente (senza usare le 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 attributo? Un po 'di confusione per me
Krizzu

Buon occhio, @Krizzu. Gli attributi esistono in JavaScript e sono cose completamente diverse dalle proprietà. La risposta si riferisce effettivamente alle proprietà e non agli attributi. Ho modificato la risposta. Non credo che al rispondente dispiacerà. :)
Ray Toal

Non sono abbastanza sicuro che questo sia davvero un tale vantaggio, in qualche modo nasconde l'idea di usare setter / getter. Un cliente di una classe può pensare di utilizzare direttamente le proprietà, laddove non è appropriato, ma sono d'accordo che aderisce al principio di nascondere le informazioni / dettagli. Forse se lo usiamo di conseguenza ne semplifica l'utilizzo e devo solo abituarmi di più ...
Christof Kälin

Puoi passare più parametri in un setter se sì, come lo usi? @David Laberge
Vignesh S

Se vuoi creare setter e getter manualmente, ecco un buon esempio da coryrylan.com/blog/javascript-es6-class-syntax Set: set name(newName) { this._name = newName; }Get:get name() { return this._name.toUpperCase(); }
Jim Doyle

48

Getter e setter in ES6 hanno lo stesso scopo che hanno in altre lingue ... incluso ES5. ES5 consente già di utilizzare getter e setter Object.defineProperty, sebbene siano meno puliti e più ingombranti da usare.

In effetti, getter e setter consentono di utilizzare la notazione di accesso alle proprietà standard per le letture e le 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 che potresti accedere alla nameproprietà in questo modo:

console.log(someEmployee.name);

Sarebbe guardare come un normale accesso alle proprietà, ma sarebbe in realtà chiamata toUpperCasesul nome prima di restituirlo. Allo stesso modo, facendo questo:

someEmployee.name = null;

accederebbe al setter, e non modificherà la _nameproprietà interna a causa della clausola di guardia introdotta nel namesetter di.

Vedi anche la domanda generale Perché usare getter e setter? per ulteriori informazioni sul motivo per cui è utile poter modificare la funzionalità di accesso ai membri.


3

Getter e setter ES6 hanno una motivazione sostanzialmente diversa rispetto a 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 una "interfaccia" completamente ortogonale rispetto a quella implicita nei campi pubblici. Quindi posso avere un "nome" di campo 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 (Hibernate per esempio) tramite la riflessione Java. 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 di "astrarre" l'implementazione. Può essere SIA un campo che un valore calcolato ("sintetico"). Quindi, se ho una proprietà bean chiamata "zipcode", questa inizia come stringa memorizzata. Supponiamo ora di volerlo modificare in modo che sia un valore calcolato da indirizzo / città / stato?

Se utilizzo un campo, questo codice si rompe:

      String zipcode = address.zipcode();

Ma se uso un getter, questo non si rompe:

      String zipcode = address.getZipcode();

JavaScript non ha nulla di simile a 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 compatibilmente un "campo" in un metodo, ES6 GET e SET lo consentono.

Cioè, se ho:

       var zipcode = address.zipcode;

Se cambio il codice postale da una proprietà oggetto standard a un getter, il codice sopra ora chiama la funzione GET.

Nota che se non includessi GET nella definizione, questo NON richiamerebbe il metodo GET del codice postale. Invece, assegnerebbe semplicemente la funzione zipcode al file var.

Quindi penso che queste siano alcune importanti distinzioni da capire tra getter e setter Java e JavaScript ES6.


0
class Employee {

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

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

    get name() {
      // when you get this by employeeInstance.mame
      // the code below will be triggered
      // and you can do some logic here
      // just like `console.log` something you want
      console.log('get triggered!')
      return this._name.toUpperCase();
    }

    set name(newName) {
      // the same as `get`
      // when you employeeInstance.mame = 'xxx'
      // the code blew will be trigged
      // and you can also do some logic 
      // like here is a `console.log` and `if check`
      console.log('set triggered!')
      if (newName) {
        this._name = newName;
      }
    }
  }

  const employeeInstance = new Employee('mike')
  employeeInstance.name
  employeeInstance.name = '' // this won't be success, because the `if check`
  console.log(employeeInstance.name)

  // => 
  // get triggered
  // set triggered
  // get triggered
  // MIKE

Comunque il gettere setterè proprio come una spia. Controlla la proprietà di un oggetto, in modo che tu possa fare qualcosa, ogni volta che ottieni o imposti il ​​valore della proprietà.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.