142 votes

Getters - setters pour les nuls

J'ai essayé de me faire une idée des getters et setters, mais je n'arrive pas à m'y faire. J'ai lu Getters et Setters JavaScript y Définition des récupérateurs et des régleurs et je ne comprends pas.

Quelqu'un peut-il affirmer clairement :

  1. Ce qu'un getter et un setter sont censés faire, et
  2. Donnez quelques exemples TRÈS simples ?

106voto

Matthew Crumley Points 47284

En plus de Réponse de @millimoose En outre, les setters peuvent également être utilisés pour mettre à jour d'autres valeurs.

function Name(first, last) {
    this.first = first;
    this.last = last;
}

Name.prototype = {
    get fullName() {
        return this.first + " " + this.last;
    },

    set fullName(name) {
        var names = name.split(" ");
        this.first = names[0];
        this.last = names[1];
    }
};

Maintenant, vous pouvez définir fullName y first y last sera mis à jour et vice versa.

n = new Name('Claude', 'Monet')
n.first # "Claude"
n.last # "Monet"
n.fullName # "Claude Monet"
n.fullName = "Gustav Klimt"
n.first # "Gustav"
n.last # "Klimt"

64voto

Beejor Points 3677

Getters et Setters en JavaScript

Vue d'ensemble

Les récupérateurs et les régleurs en JavaScript sont utilisés pour définir propriétés calculées ou accesseurs . Une propriété calculée est une propriété qui utilise une fonction pour obtenir ou définir une valeur d'objet. La théorie de base consiste à faire quelque chose comme ceci :

var user = { /* ... object with getters and setters ... */ };
user.phone = '+1 (123) 456-7890'; // updates a database
console.log( user.areaCode ); // displays '123'
console.log( user.area ); // displays 'Anytown, USA'

Cette fonction est utile pour effectuer automatiquement des opérations en coulisses lors de l'accès à une propriété, comme le maintien des nombres dans une plage, le reformatage des chaînes de caractères, le déclenchement d'événements de modification de la valeur, la mise à jour des données relationnelles, l'accès aux propriétés privées, etc.

Les exemples ci-dessous montrent la syntaxe de base, bien qu'ils se contentent de récupérer et de définir la valeur interne de l'objet sans rien faire de spécial. Dans les cas réels, vous modifierez la valeur d'entrée et/ou de sortie en fonction de vos besoins, comme indiqué ci-dessus.

get/set Mots-clés

ECMAScript 5 prend en charge get y set mots-clés pour définir les propriétés calculées. Ils fonctionnent avec tous les navigateurs modernes, à l'exception d'IE 8 et des versions inférieures.

var foo = {
    bar : 123,
    get bar(){ return bar; },
    set bar( value ){ this.bar = value; }
};
foo.bar = 456;
var gaz = foo.bar;

Getters et Setters personnalisés

get y set ne sont pas des mots réservés, ils peuvent donc être surchargés pour créer vos propres fonctions de propriétés personnalisées et calculées pour tous les navigateurs. Cela fonctionnera dans tous les navigateurs.

var foo = {
    _bar : 123,
    get : function( name ){ return this[ '_' + name ]; },
    set : function( name, value ){ this[ '_' + name ] = value; }
};
foo.set( 'bar', 456 );
var gaz = foo.get( 'bar' );

Ou pour une approche plus compacte, une seule fonction peut être utilisée.

var foo = {
    _bar : 123,
    value : function( name /*, value */ ){
        if( arguments.length < 2 ){ return this[ '_' + name ]; }
        this[ '_' + name ] = value;
    }
};
foo.value( 'bar', 456 );
var gaz = foo.value( 'bar' );

Évitez de faire une telle chose, qui peut entraîner un gonflement du code.

var foo = {
    _a : 123, _b : 456, _c : 789,
    getA : function(){ return this._a; },
    getB : ..., getC : ..., setA : ..., setB : ..., setC : ...
};

Dans les exemples ci-dessus, les noms des propriétés internes sont abrégés par un trait de soulignement afin de décourager les utilisateurs de simplement faire foo.bar vs. foo.get( 'bar' ) et obtenir une valeur "non cuite". Vous pouvez utiliser du code conditionnel pour faire différentes choses en fonction du nom de la propriété à laquelle vous accédez (via l'attribut name paramètre).

Object.defineProperty()

Utilisation de Object.defineProperty() est un autre moyen d'ajouter des getters et setters, et peut être utilisé sur des objets après leur définition. Elle peut également être utilisée pour définir des comportements configurables et énumérables. Cette syntaxe fonctionne également avec IE 8, mais malheureusement uniquement sur les objets DOM.

var foo = { _bar : 123 };
Object.defineProperty( foo, 'bar', {
    get : function(){ return this._bar; },
    set : function( value ){ this._bar = value; }
} );
foo.bar = 456;
var gaz = foo.bar;

__defineGetter__()

Enfin, __defineGetter__() est une autre option. Elle est dépréciée, mais toujours largement utilisée sur le web et ne risque donc pas de disparaître de sitôt. Elle fonctionne sur tous les navigateurs, à l'exception d'IE 10 et des versions inférieures. Bien que les autres options fonctionnent également bien sur les navigateurs autres que IE, celle-ci n'est donc pas très utile.

var foo = { _bar : 123; }
foo.__defineGetter__( 'bar', function(){ return this._bar; } );
foo.__defineSetter__( 'bar', function( value ){ this._bar = value; } );

Il convient également de noter que dans ces derniers exemples, les noms internes doivent être différents des noms des accesseurs afin d'éviter la récursion (c'est-à-dire que les noms des accesseurs doivent être différents des noms internes), foo.bar en appelant foo.get(bar) en appelant foo.bar en appelant foo.get(bar) ...).

Voir aussi

MDN obtenir , set , Object.defineProperty() , __defineGetter__() , __defineSetter__()
MSDN Support du Getter IE8

59voto

millimoose Points 22665

Vous les utiliserez par exemple pour mettre en œuvre des propriétés calculées.

Par exemple :

function Circle(radius) {
    this.radius = radius;
}

Object.defineProperty(Circle.prototype, 'circumference', {
    get: function() { return 2*Math.PI*this.radius; }
});

Object.defineProperty(Circle.prototype, 'area', {
    get: function() { return Math.PI*this.radius*this.radius; }
});

c = new Circle(10);
console.log(c.area); // Should output 314.159
console.log(c.circumference); // Should output 62.832

(CodePen)

16voto

rojo Points 3830

Désolé de ressusciter une vieille question, mais j'ai pensé que je pourrais apporter quelques exemples très basiques et des explications pour les nuls. Aucune des autres réponses postées jusqu'à présent n'illustre une syntaxe comme le Guide MDN Le premier exemple de l'auteur, qui est à peu près aussi basique qu'on puisse l'être.

Je vais chercher :

var settings = {
    firstname: 'John',
    lastname: 'Smith',
    get fullname() { return this.firstname + ' ' + this.lastname; }
};

console.log(settings.fullname);

... va enregistrer John Smith bien sûr. A getter se comporte comme une propriété d'objet variable, mais offre la flexibilité d'une fonction pour calculer sa valeur retournée à la volée. Il s'agit essentiellement d'une façon élégante de créer une fonction qui ne nécessite pas de () lors de l'appel.

Passeur :

var address = {
    set raw(what) {
        var loc = what.split(/\s*;\s*/),
        area = loc[1].split(/,?\s+(\w{2})\s+(?=\d{5})/);

        this.street = loc[0];
        this.city = area[0];
        this.state = area[1];
        this.zip = area[2];
    }
};

address.raw = '123 Lexington Ave; New York NY  10001';
console.log(address.city);

... va enregistrer New York à la console. Comme les getters, setters sont appelées avec la même syntaxe que la définition de la valeur d'une propriété d'objet, mais sont une autre façon fantaisiste d'appeler une fonction sans ().

Voir ce jsfiddle pour un exemple plus approfondi et peut-être plus pratique. Le passage de valeurs dans l'objet setter déclenche la création ou le peuplement d'autres éléments d'objet. Plus précisément, dans l'exemple de jsfiddle, le passage d'un tableau de nombres incite le setter à calculer la moyenne, la médiane, le mode et l'étendue, puis à définir les propriétés de l'objet pour chaque résultat.

12voto

Thomas E Points 141

Les récupérateurs et les régleurs n'ont vraiment de sens que lorsque vous avez des propriétés privées de classes. Étant donné que Javascript n'a pas vraiment de propriétés privées de classes comme celles auxquelles on pense normalement dans les langages orientés objet, cela peut être difficile à comprendre. Voici un exemple d'un objet compteur privé. L'avantage de cet objet est que la variable interne "count" n'est pas accessible depuis l'extérieur de l'objet.

var counter = function() {
    var count = 0;

    this.inc = function() {
        count++;
    };

    this.getCount = function() {
        return count;
    };
};

var i = new Counter();
i.inc();
i.inc();
// writes "2" to the document
document.write( i.getCount());

Si vous êtes toujours confus, jetez un coup d'œil à l'article de Crockford sur Membres privés en Javascript .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X