À quoi servent les getters et les setters dans les classes ECMAScript 6?


102

Je ne sais pas quel est l'intérêt des getters et des setters dans les classes ECMAScript 6. Quel est le but? Voici un exemple auquel je fais référence:

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
C'est similaire à ceux de C #, si vous le savez.
Arturo Torres Sánchez


Un bon article expliquant exactement cela peut être trouvé à: coryrylan.com/blog/javascript-es6-class-syntax "Dans notre classe ci-dessus, nous avons un getter et un setter pour notre propriété name. Nous utilisons la convention '_' pour créer un champ de sauvegarde pour stocker notre propriété de nom. Sans cela, chaque fois que get ou set est appelé, cela entraînerait un débordement de pile. "... Cela dit aussi que la variable n'est pas vraiment 'privée', mais il existe de nombreuses nouvelles façons de créer des variables privées dans Classes JS; mon préféré est simplement d'utiliser Typescript, mais j'ai aussi utilisé l'approche Symbol
webdevinci

Réponses:


108

Ces setter et getter vous permettent d'utiliser les propriétés directement (sans utiliser les parenthèses)

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

Il s'agit uniquement de définir et d'obtenir la valeur de la propriété.


1
Vouliez-vous dire propriété au lieu d'attribut? Un peu déroutant pour moi
Krizzu

Bon œil, @Krizzu. Les attributs existent en JavaScript et sont des choses complètement différentes des propriétés. La réponse fait en effet référence aux propriétés et non aux attributs. J'ai édité la réponse. Je ne pense pas que le répondant s'en souciera. :)
Ray Toal

Je ne suis pas sûr que ce soit vraiment un tel avantage, cela cache en quelque sorte la notion d'utilisation de setters / getters. Un client d'une classe peut penser qu'il utilise directement des propriétés, là où ce n'est pas approprié, mais je conviens qu'il adhère au principe de masquage des informations / détails. Peut-être que si nous l'utilisons, cela rend l'utilisation plus facile et je dois juste m'y habituer plus ...
Christof Kälin

Pouvez-vous passer plusieurs paramètres dans un setter si oui, comment l'utilisez-vous? @David Laberge
Vignesh S

Si vous souhaitez créer des setters et des getters manuellement, voici un bon exemple de coryrylan.com/blog/javascript-es6-class-syntax Set: set name(newName) { this._name = newName; }Get:get name() { return this._name.toUpperCase(); }
Jim Doyle

48

Les getters et les setters dans ES6 ont le même objectif que dans d'autres langues ... y compris ES5. ES5 autorise déjà les getters et les setters via Object.defineProperty, bien qu'ils soient moins propres et plus encombrants à utiliser.

En effet, les getters et les setters vous permettent d'utiliser la notation standard d'accès aux propriétés pour les lectures et les écritures tout en ayant la possibilité de personnaliser la façon dont la propriété est récupérée et mute sans les méthodes getter et setter explicites nécessaires.

Dans la classe Employee ci-dessus, cela signifierait que vous pourriez accéder à la namepropriété comme ceci:

console.log(someEmployee.name);

Cela ressemblerait à un accès normal à une propriété, mais il appellerait en fait toUpperCasele nom avant de le renvoyer. De même, faites ceci:

someEmployee.name = null;

accéderait au setter, et il ne modifierait pas la _namepropriété interne à cause de la clause de garde introduite dans namele setter de.

Voir aussi la question générale Pourquoi utiliser des getters et des setters? pour plus d'informations sur les raisons pour lesquelles il est utile de pouvoir modifier la fonctionnalité d'accès aux membres.


3

Les getters et setters ES6 ont une motivation sensiblement différente de celle des concepts similaires en Java.

En Java, les getters et les setters permettent à une classe de définir un JavaBean. L'intérêt des getters et des setters est que cela permet au bean d'avoir une "interface" complètement orthogonale à partir de celle impliquée par les champs publics. Je peux donc avoir un champ "nom" qui n'est PAS une propriété JavaBean, et je peux avoir une propriété JavaBean "adresse" qui n'est PAS un champ.

Les propriétés JavaBean sont également "découvrables" par des milliers de frameworks (Hibernate par exemple) via la réflexion Java. Ainsi, les getters et les setters font partie d'une méthode standard pour «exposer» les propriétés des haricots.

Les getters et les setters, en tant que fonctions, ont également la valeur de «faire abstraction» de l'implémentation. Il peut s'agir SOIT d'un champ ou d'une valeur calculée ("synthétique"). Donc, si j'ai une propriété bean appelée "zipcode", cela commence par une chaîne stockée. Supposons maintenant que je veuille la changer pour qu'elle soit une valeur calculée à partir de l'adresse / ville / état?

Si j'utilise un champ, ce code casse:

      String zipcode = address.zipcode();

Mais si j'utilise un getter, cela ne casse pas:

      String zipcode = address.getZipcode();

JavaScript n'a rien de comparable aux JavaBeans. Autant que j'ai lu, la valeur prévue de GET et SET est limitée aux propriétés "synthétiques" (calculées) ci-dessus.

Mais c'est un peu mieux que java dans la mesure où si Java ne vous permet pas de convertir de manière compatible un "champ" en méthode, ES6 GET et SET le permettent.

Autrement dit, si j'ai:

       var zipcode = address.zipcode;

Si je change le code postal d'une propriété d'objet standard en un getter, le code ci-dessus appelle maintenant la fonction GET.

Notez que si je n'incluais pas GET dans la définition, cela n'invoquerait PAS la méthode zipcode GET. Au lieu de cela, il affecterait simplement le code postal de la fonction au var.

Je pense donc que ce sont des distinctions importantes à comprendre entre les getters et les setters Java et 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

Quoi qu'il en soit, getteret setterc'est comme un espion. Il espionne la propriété d'un objet, afin que vous puissiez faire quelque chose, chaque fois que vous obtenez ou définissez la valeur de la propriété.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.