39 votes

Comment obtenir le nom de l'objet de classe sous forme de chaîne en Javascript?

Disons que j'instancie un objet en Javascript comme ceci:

var myObj = new someObject();

Maintenant, est-il possible d'obtenir le var nom de l'objet comme une chaîne de caractères 'myObj' depuis l'une des méthodes de la classe?


Des détails supplémentaires (modifié):

La raison pour laquelle j'aimerais avoir le nom de la variable contenant la référence à l'objet, c'est que mon nouveau myObj serait de créer un nouveau cliquable DIV sur la page qui aurait besoin d'appeler une fonction myObj.someFunction(). Comme je l'ai insérer le nouveau DIV j'ai besoin de savoir le nom de la variable contenant la référence à l'objet. Est-il peut-être une meilleure façon de faire cela?


Vous avez raison, désolé pour le problème de terminologie.

La raison pour laquelle j'aimerais avoir le nom de la variable contenant la référence à l'objet, c'est que mon nouveau myObj de créer une nouvelle DIV cliquable sur la page qui aurait besoin d'appeler une fonction myObj.someFunction(). Comme je l'ai insérer la nouvelle DIV j'ai besoin de savoir le nom de la variable contenant la référence à l'objet. Est-il peut-être une meilleure façon de faire cela?

43voto

Brian Campbell Points 101107

Shog9 est juste que cela ne fait pas beaucoup de sens de demander, car un objet peut être désigné par plusieurs variables. Si vous n'avez pas vraiment à ce sujet, et tout ce que vous voulez est de trouver le nom de l'une des variables globales qui se rapporte à cet objet, vous pouvez effectuer les opérations suivantes hack:

function myClass() { 
  this.myName = function () { 
    // search through the global object for a name that resolves to this object
    for (var name in this.global) 
      if (this.global[name] == this) 
        return name 
  } 
}
// store the global object, which can be referred to as this at the top level, in a
// property on our prototype, so we can refer to it in our object's methods
myClass.prototype.global = this
// create a global variable referring to an object
var myVar = new myClass()
myVar.myName() // returns "myVar"

Notez que c'est un vilain hack, et ne doit pas être utilisé dans le code de production. Si il n'y a plus d'une variable faisant référence à un objet, vous ne pouvez pas dire lequel vous allez obtenir. Il recherche seulement les variables globales, donc il ne fonctionnera pas si une variable est locale à une fonction. En général, si vous avez besoin de nom de quelque chose, vous devez passer le nom du constructeur, lorsque vous le créez.

edit: pour répondre À vos précisions, si vous avez besoin d'être en mesure de se référer à quelque chose d'un gestionnaire d'événements, vous ne devriez pas être fait référence par son nom, mais au lieu d'ajouter une fonction qui renvoie directement à l'objet. Voici un petit exemple que j'ai fouetté jusqu'qui montre quelque chose de similaire, je pense, de ce que vous essayez de faire:

function myConstructor () {
  this.count = 0
  this.clickme = function () {
    this.count += 1
    alert(this.count)
  }

  var newDiv = document.createElement("div")
  var contents = document.createTextNode("Click me!")

  // This is the crucial part. We don't construct an onclick handler by creating a
  // string, but instead we pass in a function that does what we want. In order to
  // refer to the object, we can't use this directly (since that will refer to the 
  // div when running event handler), but we create an anonymous function with an 
  // argument and pass this in as that argument.
  newDiv.onclick = (function (obj) { 
    return function () {
      obj.clickme()
    }
  })(this)

  newDiv.appendChild(contents)
  document.getElementById("frobnozzle").appendChild(newDiv)

}
window.onload = function () {
  var myVar = new myConstructor()
}

20voto

Shog9 Points 82052

Réponse courte: Non. myObj n'est pas le nom de l'objet, c'est le nom d'une variable contenant une référence à l'objet, vous pourriez avoir un certain nombre d'autres variables de la tenue d'une référence à l'objet même.

Maintenant, si c'est votre programme, puis vous faites les règles: si vous voulez dire que tout objet ne seront référencé par une variable, jamais, et appliquer consciencieusement que dans votre code, puis il suffit de définir une propriété sur l'objet avec le nom de la variable.

Cela dit, je doute que ce que vous demandez est en fait ce que vous voulez vraiment. Peut-être décrire votre problème en détail un peu plus...?


Pédanterie: JavaScript n'a pas de classes. someObject est une fonction constructeur. Donné une référence à un objet, vous pouvez obtenir une référence à la fonction qui l'a créé à l'aide de la propriété constructeur.


En réponse à ces détails que vous avez fournis:

La réponse que vous cherchez peut être trouvé ici: JavaScript Rappel de la Portée (et en réponse à de nombreuses autres questions sur ce que c'est un point commun de confusion pour ceux qui sont nouveaux à la JS). Vous avez juste besoin d'encapsuler l'appel à l'objet à un membre de la fermeture qui préserve l'accès à l'objet de contexte.

11voto

xaguilars Points 192

Vous pouvez le faire en convertissant le constructeur en chaîne en utilisant .toString () :

 function getObjectClass(obj){
   if (typeof obj != "object" || obj === null) return false;
   else return /(\w+)\(/.exec(obj.constructor.toString())[1];}
 

4voto

Vidar S. Ramdal Points 369

Vous pourrez peut-être atteindre votre objectif en l'utilisant dans une fonction, puis en examinant le source de la fonction avec toString() :

 var whatsMyName;

  // Just do something with the whatsMyName variable, no matter what
function func() {var v = whatsMyName;}

// Now that we're using whatsMyName in a function, we could get the source code of the function as a string:
var source = func.toString();

// Then extract the variable name from the function source:
var result = /var v = (.[^;]*)/.exec(source);

alert(result[1]); // Should alert 'whatsMyName';
 

2voto

Ekim Points 395

En tant que plus élémentaires de la situation, il serait bien SI this avaient une propriété qui pourrait de référence c'est en se référant variable (heads ou tails) mais malheureusement il ne les références de l'instanciation de la nouvelle - coinSide objet.

javascript:  /* it would be nice but ... a solution NOT! */
function coinSide(){this.ref=this};
/* can .ref be set so as to identify it's referring variable? (heads or tails) */
heads = new coinSide();
tails = new coinSide();
toss = Math.random()<0.5 ? heads : tails;
alert(toss.ref);
alert(["FF's Gecko engine shows:\n\ntoss.toSource()  is  ", toss.toSource()])

qui affiche toujours

[object Object]

et Firefox Gecko le moteur montre:

toss.toSource()  is  ,#1={ref:#1#}

Bien sûr, dans cet exemple, pour résoudre #1, et par conséquent toss, il est assez simple de test toss==heads et toss==tails. Cette question, qui est vraiment se demander si le javascript est un call-by-name mécanisme, qui motive l'examen de la contrepartie, est-il un call-by-value mécanisme pour déterminer la valeur RÉELLE d'une variable? Cet exemple montre que les "valeurs" de la les deux heads et tails sont identiques, pourtant, alert(heads==tails) est false.

L'auto-référence peut être imposée comme suit:
(en évitant l'objet de l'espace de chasse et les ambiguïtés possibles, comme indiqué dans le Comment obtenir de la classe nom de l'objet comme une chaîne de caractères en Javascript? la solution)

javascript:
function assign(n,v){ eval( n +"="+ v ); eval( n +".ref='"+ n +"'" ) }
function coinSide(){};
assign("heads", "new coinSide()");
assign("tails", "new coinSide()");
toss = Math.random()<0.5 ? heads : tails;
alert(toss.ref);

pour afficher heads ou tails.

C'est peut-être un anathème à l'essence de Javascript est le langage de conception, comme une interprétation d'une prototypage fonctionnel de la langue, d'avoir de telles capacités, comme primitives.

Une dernière considération:

 javascript:
     item=new Object(); refName="item"; deferAgain="refName";
     alert([deferAgain,eval(deferAgain),eval(eval(deferAgain))].join('\n'));

donc, comme prévu ...

javascript:
  function bindDIV(objName){ 
    return eval( objName +'=new someObject("'+objName+'")' )
  };
  function someObject(objName){
    this.div="\n<DIV onclick='window.opener."+   /* window.opener - hiccup!! */
               objName+
             ".someFunction()'>clickable DIV</DIV>\n";
    this.someFunction=function(){alert(['my variable object name is ',objName])}
  };
  with(window.open('','test').document){         /*     see above hiccup    */
    write('<html>'+
      bindDIV('DIVobj1').div+
      bindDIV('DIV2').div+
      (alias=bindDIV('multiply')).div+
      'an aliased DIV clone'+multiply.div+
      '</html>');
    close();
  };
  void (0);

Est-il une meilleure façon ... ?

"mieux", comme dans la plus facile? Plus facile à programmer? Plus facile à comprendre? Plus facile que dans une exécution plus rapide? Ou est-ce que dans "... et maintenant pour quelque chose de complètement différent"?

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