2017-09-19 12 views
0

J'ai une fonction qui définit un getter et un setter sur un objet ou un tableau. Mon problème est que si la valeur définie est un objet, je ne peux pas détecter ses changements internes, mais seulement quand on y accède en supposant que l'on y accède via le getter. Au moment où le getter retourne l'objet mais je veux effectuer une action après avoir renvoyé le getter s'il a été changé ou non.Effectuer une action après le retour d'un getter

Mon code au moment:

set = function(obj, i, val) { 
    Object.defineProperty(obj, i, { 
     set(newVal) { 
      val = newVal 
      // react to changes 
      insert(val, i) 
     }, 
     get() { 
      return val 
      //I want this to run after the object was accessed and possibly changed 
      if (typeof val == "object") { 
       insert(val, i) 
      } 
     }, 
     configurable: true, 
     enumerable: true 
    }) 
} 

J'ai pensé à une solution qui est setTimeout si le poseur et getter sont supprimés le setTimeout peut provoquer un comportement indésirable et je préférerais le code resté synchrone.

L'autre idée que j'ai considérée est la définition de setters et getters sur toutes les propriétés des objets, mais cela serait coûteux.

Comment puis-je résoudre ce problème?

+0

* "Toutefois, si setter et getter sont supprimés, setTimeout peut provoquer un comportement indésirable" * Huh? –

+0

Vous pouvez geler l'objet ou utiliser une bibliothèque comme Immutablejs, de sorte que la seule façon de mettre à jour l'objet est de le repositionner. –

+0

Cela ressemble à un problème X/Y. Quel est le problème sous-jacent que vous essayez de résoudre? –

Répondre

1

J'ai pensé à une solution qui est setTimeout ...

Voilà comment vous le faites, cela ou Promise.resolve().then(...).

... et je préfère que le code reste synchrone.

Il ne peut pas être synchrone. Vous pouvez effectuer une action après le retour du getter, ou il peut être synchrone. Vous ne pouvez pas l'avoir dans les deux sens.


Cela dit, il n'y a aucune garantie que quelque chose asynchrone faire peu de temps après le getter est utilisé détectera rien fait avec l'objet. Considérez:

var o = yourObject.theProperty; 
setTimeout(function() { 
    o.foo = "bar"; 
}, 6000); 

Votre getter sur theProperty est exécuté sur la première ligne. L'objet n'est pas changé jusqu'à six secondes plus tard.

Si vous souhaitez détecter , modifiez l'objet, puis attribuez à toutes ses propriétés les propriétés getter/setter qui ne peuvent pas être reconfigurées et effectuez les modifications que vous voyez. (Vous pouvez également utiliser Object.freeze ou Object.seal pour empêcher l'ajout de nouvelles propriétés.)

Si vous voulez que l'objet puisse avoir des propriétés que vous n'avez pas définies, mais que vous voulez toujours réagir aux modifications, ll doit utiliser un Proxy, avec le coup de performance concomitant. Mais pour un ensemble de propriétés connu, les propriétés getter/setter non configurables effectuent le travail.