2 votes

Existe-t-il un moyen de détecter si les propriétés d'un objet ont été modifiées ?

Comment détecter si les propriétés d'un objet ont changé en Javascript ? Je cherche spécifiquement à appeler une fonction lorsque le nombre de propriétés d'un objet a changé (s'il a gagné ou perdu des propriétés). J'aimerais éviter d'utiliser des méthodes pour définir et modifier les propriétés de l'objet, car cela deviendrait rapidement maladroit, et setInterval n'est évidemment pas une option. Alors, est-ce possible ?


Edit : Je cherche spécifiquement un moyen d'obtenir la longueur des propriétés d'un objet via une fonction length similaire à celle de l'objet Array. Je supposais qu'ils modifiaient la longueur à chaque fois qu'un indice était ajouté ou supprimé, mais apparemment ce n'est pas le cas. Comment les concepteurs originaux de Javascript ont-ils géré cela ?

2voto

Joseph the Dreamer Points 43727

Eh bien, la façon courante de le faire est d'avoir un type de fonctions getter et setter pour le faire, similaire à la façon dont Backbone fait ses modèles. Vous modifiez les données via la fonction, puis la fonction effectue un traitement supplémentaire (comme l'exécution des écouteurs, la vérification des propriétés, etc.) avant d'exécuter ce que vous voulez faire.

function ListenableObject(data){

    var that = this;
    this.data = data;
    this.listeners = [];

    this.edit = function(newvalues){
        //modify data
        //execute listeners
    }

    this.addListener = function(callback){
        that.listeners.push(callback);
    }
}

var mydata = new ListenableObject({'foo':'bar'});

mydata.addListener(function(){...callback...});

mydata.edit(somedata);

1voto

ajax81 Points 3215

La réponse courte, basée sur vos exigences, est qu'il n'est pas possible de faire ce que vous essayez de faire. Du moins, pas encore. Il existe quelques techniques que vous pouvez utiliser pour obtenir la même fonctionnalité avec un impact minimal sur votre code. Voici l'une de mes techniques préférées, découverte quelque part sur SO - je ferai un lien si je la trouve.

function myObj(){

   var _this = this;

   // onUpdate callbacks
   this.onBeforeUpdate = [];
   this.onAfterUpdate  = [];

   this.UpdateProperty = function( prop, value ){

      // execute onBeforeUpdate callbacks...  
      for ( var i = 0; i < _this.onBeforeUpdate.length; i++ )
         _this.onBeforeUpdate[i]();

      _this[prop] = value;

      // execute onAfterUpdate callbacks...
      for ( var i = 0; i < _this.onAfterUpdate.length; i++ )
         _this.onAfterUpdate[i]();
   };

}

Bien sûr, cet exemple peut être encore plus performant avec une utilisation libérale des affectations de prototypes, mais vous pouvez voir l'intention.

1voto

Šime Vidas Points 59994

Donc, pour résumer tout ce que j'ai dit via les commentaires : ES6 fournira des proxies qui devraient permettre de gérer des événements comme "nouvelle propriété", ou "propriété supprimée". (Malheureusement, il faudra des années avant que les proxies ne deviennent multi-navigateurs.

Quant à, la length pour les objets, vous pourriez définir une fonction getter pour cela, mais cela ne fonctionnerait pas dans IE8, car IE n'a mis en œuvre les getters que dans IE9. Il ne vous reste donc qu'une fonction length() méthode. Donc :

function objectLength () {
    return Object.keys( this ).length;
}

et ensuite, vous vous assurez que votre objet possède cette fonction (soit comme une propriété propre, soit comme une propriété héritée) :

yourObj.length = objectLength;

o

YourConstructor.prototype.length = objectLength;

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