2014-09-04 3 views
0

Existe-t-il un moyen d'attraper une fonction de jeu Javascript dans defineProperty, d'effectuer une certaine logique et de décider si la fonction set d'origine doit être invoquée?invoquer/empêcher conditionnellement invocation de setter dans l'objet defineProperty de Javascript

Exemple

var scope = {}; 
scope.myVar = 1; 

scope._myVar = scope.myVar; 
Object.defineProperty(scope, "myVar", { 
    get: function(){ 
    return scope._myVar; 
    }, 
    set: function(val) { 
    scope._myVar = val; 
    //Do some other work 
    } 
} 

//Now when scope.myVar is changed, its setter is invoked 
//I would like to write some code here now that will run even before the 
//myVar setter, do some work, and then decide whether to invoke the setter 
//or not. If it decides to not invoke the setter, then it will be as 
//though the scope.myVar = ... was never called. 

//Psuedo-code 
scope._setMyVar = scope.setMyVar; 
scope.setMyVar = function(val) { 
    //do some work 
    var condition = resultOfWorkAbove; 

    if(condition) { 
    scope._setMyVar(val); 
    } 
} 

Répondre

2

Oui, il y a. Vous pouvez obtenir l'ancien setter (ce que vous avez écrit scope._setMyVar = scope.setMyVar; dans votre pseudo-code) avec Object.getOwnPropertyDescriptor().

(function(obj, prop) { // an IEFE for local variables 
    var desc = Object.getOwnPropertyDescriptor(obj, prop), 
     oldsetter = desc.set; 
    desc.set = function(val) { 
     var condition = … // do some work; 
     if (condition) 
      oldsetter.call(this, val); 
    }; 
    Object.defineProperty(obj, prop, desc); 
}(scope, "myVar")); 

Bien sûr, cela ne fonctionne que si le descripteur de propriété d'origine avait configurable set to true, sinon on ne peut pas le remplacer.

+0

Super travail @Bergi. Je n'en avais aucune idée. C'est très difficile et je suppose que c'est incroyablement facile de viser mon propre pied. :) –

+1

Ouais, appeler cela sur une propriété de données (pas un accesseur) fera mal par exemple :-) – Bergi

+0

Je cours ce code sur IE10 sans paramètre configurable à vrai et ça fonctionne bien. Lorsque je fais une recherche sur la propriété configurable, je la vois par défaut à false. Bizarre. –

Questions connexes