41 votes

Est-il un équivalent de l' __noSuchMethod__ fonctionnalité pour les propriétés, ou un moyen de la mettre en œuvre en JS?

Il y a un noSuchMethod fonctionnalité dans certaines implémentations de javascript (Rhino, SpiderMonkey)

proxy = {
    __noSuchMethod__: function(methodName, args){
        return "The " + methodName + " method isn't implemented yet. HINT: I accept cash and beer bribes" ;
    },

    realMethod: function(){
     return "implemented" ;   
    }
}

js> proxy.realMethod()
implemented
js> proxy.newIPod()
The newIPod method isn't implemented yet. HINT: I accept cash and beer bribes
js>

Je me demandais, est il y avait moyen de faire quelque chose de similaire pour les propriétés? Je voudrais écrire des classes de proxy qui peut envoyer sur les propriétés ainsi que les méthodes.

65voto

CMS Points 315406

Il y a une seule chose en ce moment qui peut réellement faire ce que vous voulez, mais, malheureusement, n'est pas largement mis en œuvre:

Il y a seulement deux implémentations disponibles à ce moment, dans le dernier Firefox 4 bêta (il a été autour depuis FF3.7 pré-versions) et dans le nœud de serveur proxy pour JavaScript côté serveur -Chrome et Safari sont actuellement en train de travailler sur lui-.

C'est l'une des premières propositions pour la prochaine version de ECMAScript, c'est une API qui permet de mettre en œuvre virtualisé objets (par procuration), où vous pouvez assigner une variété de pièges -rappels - qui sont exécutés dans des situations différentes, vous prendre le plein contrôle sur ce qu'à ce moment -dans ECMAScript 3/5 - seuls les objets hôte pourrait le faire.

Pour construire un objet proxy, vous devez utiliser l' Proxy.create méthode, puisque vous vous intéressez à l' set et get pièges, je vous laisse vraiment un exemple simple:

var p = Proxy.create({
  get: function(proxy, name) {        // intercepts property access
    return 'Hello, '+ name;
  },
  set: function(proxy, name, value) { // intercepts property assignments
    alert(name +'='+ value);
    return true;
  }
});

alert(p.world); // alerts 'Hello, world'
p.foo = 'bar';  // alerts foo=bar

Essayer ici.

Le Proxy de l'API est donc de nouveau qui n'est pas encore documenté sur le Mozilla Developer Center, mais comme je l'ai dit, un travail de mise en œuvre a été inclus depuis le Firefox 3.7 pré-versions.

L' Proxy objet est disponible dans la portée globale et l' create méthode peut prendre deux arguments, un handler de l'objet, qui est simplement un objet qui contient des propriétés nommées comme des pièges que vous souhaitez mettre en œuvre, et une option proto argument, qui vous rend capable de spécifier un objet que votre proxy hérite.

Les pièges sont disponibles:

// TrapName(args)                          Triggered by
// Fundamental traps
getOwnPropertyDescriptor(name):           // Object.getOwnPropertyDescriptor(proxy, name)
getPropertyDescriptor(name):              // Object.getPropertyDescriptor(proxy, name) [currently inexistent in ES5]
defineProperty(name, propertyDescriptor): // Object.defineProperty(proxy,name,pd)
getOwnPropertyNames():                    // Object.getOwnPropertyNames(proxy) 
getPropertyNames():                       // Object.getPropertyNames(proxy) 
delete(name):                             // delete proxy.name
enumerate():                              // for (name in proxy)
fix():                                    // Object.{freeze|seal|preventExtensions}(proxy)

// Derived traps
has(name):                                // name in proxy
hasOwn(name):                             // ({}).hasOwnProperty.call(proxy, name)
get(receiver, name):                      // receiver.name
set(receiver, name, val):                 // receiver.name = val
keys():                                   // Object.keys(proxy)

La seule ressource que j'ai vu, en plus de la proposition en elle-même est le tutoriel suivant:

Edit: Plus l'information est en train de sortir, Brendan Eich a récemment donné une conférence à l' JSConf.ue de la Conférence, vous pouvez trouver ses diapositives ici:

3voto

burkestar Points 518

Je ne crois pas que ce type de métaprogrammation est possible (encore) en javascript. Au lieu de cela, essayez d'utiliser l' __noSuchMethod__ fonctionnalités pour obtenir l'effet avec la propriété getters. Croix-navigateur, comme c'est une extension de Mozilla.

var proxy = {
    __noSuchMethod__: function(methodName, args) {
       if(methodName.substr(0,3)=="get") {
          var property = methodName.substr(3).toLowerCase();                             
          if (property in this) {
              return this[property];
          }
       }
    }, color: "red"
 };
 alert(proxy.getColor());           

0voto

radiospiel Points 1342

Il est __defineGetter__, __defineSetter__, __lookupGetter__ et __lookupSetter__ de plus de __noSuchMethod__ dans SpiderMonkey. Voir ici: http://offthelip.org/?p=101

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