Come ottenere il nome dell’object di class come stringa in Javascript?

Diciamo che istanzia un object in Javascript in questo modo:

var myObj = new someObject(); 

Ora, è ansible ottenere il nome dell’object var come stringa 'myObj' da uno dei metodi di class?


Ulteriori dettagli (a cura di):

Il motivo per cui mi piacerebbe ottenere il nome della variabile contenente riferimento all’object è che il mio nuovo myObj creerebbe un nuovo DIV selezionabile nella pagina che avrebbe bisogno di chiamare una funzione myObj.someFunction() . Mentre inserisco il nuovo DIV ho bisogno di conoscere il nome della variabile che contiene il riferimento all’object. C’è forse un modo migliore per farlo?


Hai ragione, mi dispiace per la confusione terminologica.

Il motivo per cui mi piacerebbe ottenere il nome della variabile contenente riferimento all’object è che il mio nuovo myObj creerebbe un nuovo DIV selezionabile nella pagina che avrebbe bisogno di chiamare una funzione myObj.someFunction (). Mentre inserisco il nuovo DIV ho bisogno di conoscere il nome della variabile che contiene il riferimento all’object. C’è forse un modo migliore per farlo?

Shog9 ha ragione nel dire che questo non ha molto senso chiedere, dal momento che un object può essere definito da più variabili. Se non ti interessa davvero, e tutto ciò che vuoi è trovare il nome di una delle variabili globali che si riferiscono a quell’object, puoi fare il seguente trucco:

 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" 

Si noti che si tratta di un brutto attacco e non dovrebbe essere utilizzato nel codice di produzione. Se c’è più di una variabile che si riferisce a un object, non puoi dire quale otterrai. Cerca solo le variabili globali, quindi non funzionerà se una variabile è locale a una funzione. In generale, se hai bisogno di nominare qualcosa, dovresti passare il nome al costruttore quando lo crei.

modifica : per rispondere al tuo chiarimento, se devi essere in grado di fare riferimento a qualcosa da un gestore di eventi, non dovresti riferirti ad esso per nome, ma piuttosto aggiungi una funzione che si riferisce direttamente all’object. Ecco un rapido esempio che ho creato per mostrare qualcosa di simile, penso, a quello che stai cercando di fare:

 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() } 

Risposta breve: No. myObj non è il nome dell’object, è il nome di una variabile che contiene un riferimento all’object – potresti avere un numero qualsiasi di altre variabili che contengono un riferimento allo stesso object.

Ora, se è il tuo programma, allora fai le regole: se vuoi dire che ogni dato object sarà referenziato da una variabile, mai, e applica diligentemente quello nel tuo codice, quindi imposta semplicemente una proprietà sull’object con il nome della variabile.

Detto questo, dubito che quello che chiedi sia in realtà ciò che vuoi veramente. Forse descrivi il tuo problema in modo più dettagliato …?


Pedanteria: JavaScript non ha classi. someObject è una funzione di costruzione. Dato un riferimento a un object, è ansible ottenere un riferimento alla funzione che lo ha creato utilizzando la proprietà del costruttore .


In risposta ai dettagli aggiuntivi che hai fornito:

La risposta che stai cercando può essere trovata qui: JavaScript Callback Scope (e in risposta a numerose altre domande su SO – è un punto comune di confusione per chi è nuovo a JS). Hai solo bisogno di avvolgere la chiamata al membro dell’object in una chiusura che preserva l’accesso all’object di contesto.

Puoi farlo convertire dal costruttore in una stringa usando .toString () :

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

Potresti essere in grado di raggiungere il tuo objective usandolo in una funzione e quindi esaminando la sorgente della funzione con 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'; 

Se non si desidera utilizzare un costruttore di funzioni come nella risposta di Brian, è ansible utilizzare Object.create () invece: –

 var myVar = { count: 0 } myVar.init = function(n) { this.count = n this.newDiv() } myVar.newDiv = function() { var newDiv = document.createElement("div") var contents = document.createTextNode("Click me!") var func = myVar.func(this) newDiv.addEventListener ? newDiv.addEventListener('click', func, false) : newDiv.attachEvent('onclick', func) newDiv.appendChild(contents) document.getElementsByTagName("body")[0].appendChild(newDiv) } myVar.func = function (thys) { return function() { thys.clickme() } } myVar.clickme = function () { this.count += 1 alert(this.count) } myVar.init(2) var myVar1 = Object.create(myVar) myVar1.init(55) var myVar2 = Object.create(myVar) myVar2.init(150) // etc 

Stranamente, non sono riuscito a far funzionare il lavoro sopra usando newDiv.onClick, ma funziona con newDiv.addEventListener / newDiv.attachEvent.

Poiché Object.create è nuovo, includi il seguente codice di Douglas Crockford per i browser più vecchi, incluso IE8.

 if (typeof Object.create !== 'function') { Object.create = function (o) { function F() {} F.prototype = o return new F() } } 

Come situazione più elementare sarebbe bello se this avesse una proprietà che potesse fare riferimento alla variabile di riferimento ( heads o tails ) ma sfortunatamente si riferisce solo all’istanza del nuovo object coinSide .

 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()]) 

che mostra sempre

 [object Object] 

e il motore Gecko di Firefox mostra:

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

Ovviamente, in questo esempio, per risolvere il #1 , e quindi toss , è abbastanza semplice testare toss==heads e toss==tails . Questa domanda, che in realtà chiede se javascript ha un meccanismo call-by-name , motiva la considerazione della controparte, esiste un meccanismo call-by-value per determinare il valore ACTUAL di una variabile? L'esempio dimostra che i "valori" di entrambe le heads e le tails sono identici, ma l' alert(heads==tails) è false .

L'autoreferenzialità può essere forzata come segue:
(evitando la caccia allo spazio dell'object e le possibili ambiguità come indicato nel come ottenere il nome dell'object class come stringa nella soluzione Javascript? )

 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); 

per mostrare heads o tails .

È forse un anatema per l'essenza del linguaggio design di Javascript, come linguaggio funzionale prototipato interpretato, per avere capacità come primitive.

Un'ultima considerazione:

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

quindi, come previsto ...

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

C'è un modo migliore ... ?

"migliore" come in più facile? Più facile da programmare? Più facile da capire? Più facile come nell'esecuzione più veloce? O è come in " ... e ora per qualcosa di completamente diverso "?

Immediatamente dopo che l’object è istantaneo, puoi albind una proprietà, ad esempio name , all’object e assegnare il valore di stringa che ti aspetti:

 var myObj = new someClass(); myObj.name="myObj"; document.write(myObj.name); 

In alternativa, l’assegnazione può essere effettuata all’interno dei codici della class, ad es

 var someClass = function(P) { this.name=P; // rest of the class definition... }; var myObj = new someClass("myObj"); document.write(myObj.name); 

Qualche tempo fa, ho usato questo.

Forse potresti provare:

 +function(){ var my_var = function get_this_name(){ alert("I " + this.init()); }; my_var.prototype.init = function(){ return my_var.name; } new my_var(); }(); 

"I get_this_name" un avviso : "I get_this_name" .

Questo è piuttosto vecchio, ma mi sono imbattuto in questa domanda tramite Google, quindi forse questa soluzione potrebbe essere utile per gli altri.

 function GetObjectName(myObject){ var objectName=JSON.stringify(myObject).match(/"(.*?)"/)[1]; return objectName; } 

Usa solo il parser JSON del browser e la regex senza ingombrare troppo il DOM o il tuo object.