2009-05-08 7 views
5

J'aimerais obtenir le nom de la variable.Comment obtenir le nom d'une classe Mootools depuis

var Poop = new Class({ 
    getClassName: function() { 
     return arguments.callee._owner.name; 
    } 
}); 
var a = new Poop(); 
a.getClassName(); //want 'Poop' 

je fais qui sera mis en œuvre dans d'autres classes, et je voudrais construire une requête SQL qui utilise le nom de la classe (pluralisé) pour la table.

J'ai essayé différentes combinaisons de l'exemple ci-dessus pour essayer d'obtenir le nom, et je n'arrive pas à le comprendre (même si cela est possible compte tenu du système de classe de MooTools).

Répondre

8

Trouvé une solution. Hash has a keyOf function, ce qui me donnera le nom de la variable qui contient une valeur. J'ai donc fait un Hash of window, puis j'ai demandé la clé du constructeur de la classe.

var Poop = new Class({ 
    name: function() { 
     var w = $H(window); 
     return w.keyOf(this.constructor); 
    } 
}); 
var a = new Poop(); 
a.name(); // returns 'Poop' 

Bien sûr, cela ne fonctionne que parce que je crée des classes dans l'espace de noms global de la fenêtre (comme cela est courant avec MooTools). Si vous avez créé des classes à l'intérieur d'un espace de noms, vous devrez simplement Hasher cet espace de noms à la place.

Editer: I wrote up sur comment utiliser cette solution et comment la faire fonctionner dans les espaces de noms automatiquement, pour tous les MooToolers intéressés.

0

Je ne pense pas que ce soit possible en Javascript, en raison de la nature orientée prototype du langage. Il y a plusieurs choses que vous pouvez faire pour déterminer si un objet est d'une classe existante que vous savez, comme:

if (a.constructor == Poop) { 
    alert("This will work, but I don't really want any Poop."); 
} 

Cependant, cela ne fonctionne pas vraiment pour la détermination de la classe d'un objet inconnu. Il y a d'autres choses que vous pouvez faire pour vérifier la classe qui impliquent toString(), mais ils ne fonctionnent que pour les objets intégrés, pas pour les classes personnalisées, et c'est un inconvénient du prototypage qui n'est pas spécifique à MooTools.

Si vous consultez le 5th Edition of Javascript, The Definitive Guide, page 174, chapitre 9.7, il y a une discussion intéressante à ce sujet. Fondamentalement, la recommandation consiste à remplir vos classes personnalisées avec une propriété classname et à remplacer la méthode par défaut de la classe d'objet toString() pour vérifier cette propriété lorsque vous l'appelez dans une classe personnalisée.

2

je suis tombé sur un problème avec Prolonge, mais a trouvé un moyen de contourner:

var getClassNameFromKeys = function (obj, instance) { 
     var i = 0, keys = Object.keys(obj); 
     for (i; i < keys.length; i++) { 
     if ('Ext' !== keys[i] && typeOf(obj[keys[i]]) === 'class' && instance instanceof obj[keys[i]]) { 
       return keys[i]; 
      } 
     } 
    }, 
    Ext = new Class(), 
    WhatsMyName = new Class({ 
     Extends: Ext 
    }), 
    whatsMyNameInstance = new WhatsMyName(), 
    cName = getClassNameFromKeys(this, whatsMyNameInstance); 

console.log(cName); 

Vous pouvez éviter le contrôle sur le nom étend si vous suivez un quelque chose comme modèle ceci:

var O = {}, 
    whatsMyNameInstance; 

(function() { 
    var SUBCLASS_KEYS; 

    O.Ext = new Class({ 
     _className: null, 
     getClassName: function() { 
      var i = 0; 

      SUBCLASS_KEYS = SUBCLASS_KEYS || Object.keys(O.subclasses); 

      for (i; i < SUBCLASS_KEYS.length; i++) { 
      if (this instanceof O.subclasses[SUBCLASS_KEYS[i]]) { 
        return SUBCLASS_KEYS[i]; 
       } 
     } 
     }   
    }); 
})(); 

O.subclasses = {}; 

O.subclasses.WhatsMyName = new Class({ 
    Extends: O.Ext 
}); 

whatsMyNameInstance = new O.subclasses.WhatsMyName(); 

whatsMyNameInstance.getClassName(); 
Questions connexes