Des propriétés non énumérables dans un objet Javascript

Cet article a été publié depuis plus de 6 mois, cela signifie que le contenu peut ne plus être d'actualité.

Dans un article précédent, je parlais de comment créer des objets en Javascript en utilisant les prototypes. Mais le fonctionnement par défaut du langage implique que les propriétés de votre objet sont énumérables. De ce fait, elles seront listées au sein d'une boucle for...in par exemple.

En reprenant l'exemple précédent :

function MyObject() {
    this.myProperty1 = null;
    this.myProperty2 = null;
}

MyObject.prototype.myMethod1 = function() {
    return 'method1';
}

MyObject.prototype.myMethod2 = function(param1, param2) {
    return 'method2';
}

var myInstance = new MyObject();

var properties = [];
for (var prop in myInstance) {
    properties.push(prop);
}

console.log(properties); // => [ 'myProperty1', 'myProperty2', 'myMethod1', 'myMethod2' ]

Il peut être dérangeant dans certains cas que les éléments constituants de notre objet soient énumérables. Pour éviter cela, la solution est d'utiliser la méthode Object.defineProperty(). Cette dernière permet de définir une nouvelle propriété ou d'en modifier une existante. Elle permet également de définir le comportement de la propriété ajoutée.

Il est donc possible de définir une contrainte enumerable à false afin d'éviter que les propriétés n'apparaissent dans les boucles.

Notre objet peut donc être défini ainsi :

function MyObject() {
    this.myProperty1 = null;
    this.myProperty2 = null;
}

Object.defineProperty(MyObject.prototype, "myMethod1", {
    enumerable: false,
    value: function() {
        return 'method1';
    }
});

Object.defineProperty(MyObject.prototype, "myMethod2", {
    enumerable: false,
    value: function() {
        return 'method2';
    }
});

var myInstance = new MyObject();

var properties = [];
for (var prop in myInstance) {
    properties.push(prop);
}

console.log(properties); // => [ 'myProperty1', 'myProperty2' ]

Object.defineProperty() propose également une option writable qui permet d'empêcher la modification d'une propriété de l'objet.

Si vous souhaitez obtenir plus d'information sur le fonctionnement de Object.defineProperty(), je vous invite à consulter la documentation developeur de Mozilla.