12 votes

Existe-t-il un moyen d'empêcher le remplacement des propriétés des objets JavaScript ?

Je voudrais rendre la structure d'un objet immuable, en empêchant ses propriétés d'être remplacées ultérieurement. Les propriétés doivent cependant être lisibles. Est-ce possible ?

Je suis sûr qu'il n'existe pas de fonctionnalités linguistiques (du type final en Java et readonly en C#) pour prendre en charge cette fonction, mais je me suis demandé s'il n'existait pas un autre mécanisme permettant d'obtenir le même résultat.

Je suis à la recherche de quelque chose de ce genre :

var o = {
    a: "a",
    f: function () {
        return "b";
    }
};

var p = o.a;        // OK
o.a = "b";          // Error
var q = o.f();      // OK
o.f = function () { // Error
    return "c"; 
};

14voto

EndangeredMassa Points 9532

ECMAScript 5 aura seal() y freeze() mais il n'y a pas de bon moyen de le faire avec les implémentations actuelles de JavaScript.

Fuente .

9voto

mkoryak Points 18135

La meilleure chose que vous puissiez faire est de cacher vos propriétés à l'intérieur d'une fermeture.

var getMap = function(){
  var hidden = "1";
  return {
    getHidden : function() { return hidden; }
  }
}

var f = getMap ();

alert(f.getHidden());

J'ai tenté de le faire. Dans le code ci-dessus, vous ne devez pas seulement renvoyer hidden mais aussi le copier dans un nouvel objet. Vous pouvez peut-être utiliser extend de jquery pour le faire pour vous, ainsi vous renverrez un nouvel objet et non la référence. Cela peut être complètement faux cependant =)

5voto

Josh Stodola Points 42410

Utilisation de var dans un constructeur d'objet va créer une variable privée. Il s'agit essentiellement d'une fermeture. Vous pouvez ensuite créer une fonction publique pour y accéder ou la modifier. Plus d'informations et d'exemples disponibles sur Membres privés en Javascript par Douglas Crockford.

4voto

Chetan Sastry Points 14742

Comme l'a dit mkoryak, vous pouvez créer une fermeture pour masquer les propriétés

function Car(make, model, color) {
    var _make = make, _model = model, _color = color; 

    this.getMake = function() {
        return _make;
    }

}

var mycar = new Car("ford", "mustang", "black");

mycar.getMake(); //returns "ford"
mycar._make; //error

4voto

Zecc Points 2385

Bon, il y a déjà eu quelques réponses suggérant de renvoyer un objet avec plusieurs méthodes getters. Mais vous pouvez toujours remplacer ces méthodes.

Il y a ça, qui est légèrement mieux. Vous ne pourrez pas remplacer les propriétés de l'objet sans remplacer complètement la fonction. Mais ce n'est toujours pas exactement ce que vous voulez.

function Sealed(obj) {
    function copy(o){
        var n = {}; 
        for(p in o){
            n[p] = o[p]
        }
        return n;
    }
    var priv = copy(obj);
    return function(p) {
        return typeof p == 'undefined' ? copy(priv) : priv[p];  // or maybe copy(priv[p])
    }
}

var mycar = new Sealed({make:"ford", model:"mustang", color:"black"});

alert( mycar('make') ); // "ford"
alert( mycar().make );  // "ford"

var newcopy = mycar();
newcopy.make = 'volkwagen';
alert( newcopy.make ); // "volkwagen"  :(

alert( mycar().make );   // still "ford"  :)
alert( mycar('make') );   // still "ford" :)

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