JavaScript: Ottieni valore argomento e NOME della variabile superata

Quello che voglio fare è ottenere il NOME di una variabile passata a una funzione e il VALORE di quella variabile e solo passare una variabile alla funzione. Così:

var x = "anything"; function showName() { } showName(x); 

o

 showName("x"); 

Che restituirà: “x = qualsiasi cosa”.

In questo momento, devo fare:

 showName("x", x); 

per ottenere il nome e il valore della variabile che sto passando. Nota che non mi interessa il nome dell’argomento nel prototipo di showName, ma il nome della variabile nella funzione chiamante. Inoltre, la variabile potrebbe essere locale, quindi non posso usare l’object window per trovare la variabile.

La risposta breve è che non puoi.

Più a lungo, la risposta malvagia è che si può ottenere con una certa cattiveria. E funziona solo quando chiamato da un’altra funzione.

ci sono due attributi interessanti a tua disposizione che potrebbero aiutarti

arguments.callee chiamante

per fn fare qualcosa del genere:

 (function(){ var showMe = function(s){ alert(arguments.callee.caller.toString().match(/showMe\((\S)\)/)[1] + ' = '+ s) } x = 1 showMe(x) })() 

Che arguments.callee.caller.toString (). Match (..) [1] fa è cercare lo showMe che viene chiamato nella funzione che lo chiama e lo stampa e il suo valore.

Ma questo è ancora abbastanza limitato perché colpirà solo la prima chiamata di showMe (x). Quindi, se ci sono due chiamate, non funzionerà.

Ma è stato divertente giocare con queste cose arcane.

 var x = "anything"; function showName(s) { alert(s + " = " + eval(s)); } showName("x"); 

Non consigliato, ma è così.

Sapevo già che potevo passare in un object:

 {a:"this is a"} 

dove a è il nome della variabile ma in realtà voglio solo passare una variabile o il nome di una variabile (a o “a”) e lasciare che la funzione trovi in ​​qualche modo il nome della variabile e il suo valore.

La ragione per cui voglio fare questa cosa un po ‘strana è che sto scrivendo una routine di stampa di debug. Se lo chiamo in questo modo:

 var x = "some string"; say(x); 

o

 say("x"); 

Voglio che stampi qualcosa del tipo:

 X (string) = some string 

Posso scoprire in modo affidabile il tipo di variabile passato, quindi so come stamparlo, ma voglio davvero provare a evitare la ridondanza di doverlo chiamare in questo modo:

 say("x", x); 

che è quello che devo fare ora.

Ciò che sembra quasi funzionare è la risposta di OrbMan. Certo, eval è malvagio , ma penso che sia OK qui perché è solo per un’utilità di debug e non sarà nel codice pubblicato. Ho fatto una mia piccola routine di test usando questa soluzione:

 var x = "this is x"; function say(a) { alert(a + " = " + eval(a)); } say("x"); 

e funziona ma SOLO SE X È GLOBALE . Questo non funziona:

 function wrapper() { var x = "this is x"; say("x"); } 

Quindi, questa soluzione è vicina, ma poiché non utilizzo quasi nessuna variabile globale, questo non funzionerà. Maledizione, è così vicino. Quello che penso di cui ho bisogno è “chiama per nome” anziché “per valore” o “per riferimento”. E ho bisogno di una funzione che funzioni sia che venga chiamata da un’altra funzione o meno.

Dato che ci ho messo un sacco di ore su questo, ponendo la domanda qui è stato un atto di disperazione, devo concludere che non c’è davvero alcun modo per farlo. Shucks.

A tutti quelli che hanno risposto, grazie per tutto il vostro aiuto.

Potresti creare un hash e passarlo in:

 var x = {a: 1,b:2} function showVars(y) { for (var z in y) { alert(z + " is " + y[z]); } } showVars(x); 

Questo non mostra necessariamente il nome della variabile, ma consente coppie di valori-chiave, che potrebbero essere più pertinenti a ciò di cui hai bisogno.

Questo è quello che uso per il debug. Nessuna variabile globale, nessuna valutazione, nessuna discussione.cassa o argomento.caller:

 var Helpers = (function () { // ECMAScript 5 strict mode 'use strict'; var Module = {}; Module.debug = function () { var i; for (i = 0; i < arguments.length; i++) { console.log(arguments[i] + ':', this[arguments[i]]); } }; Module.SomeObject = function SomeObject() { this.someMember = 1; this.anotherMember = 'Whatever'; Module.debug.call(this, 'someMember', 'anotherMember'); var privateMember = { name: 'Rip Steakface', battleCry: 'Raaaaaaaaahhhhhhhhhrrrrrrrrrg!' }; Module.debug.call(privateMember, 'name', 'battleCry'); }; return Module; }()); 

Per coloro che si stanno chiedendo perché vorresti farlo, è solo un modo per registrare in modo efficiente più variabili insieme ai loro nomi.

Se vuoi essere in grado di registrare membri annidati, come in Module.debug.call(obj, 'hair.fluffiness') , puoi modificare la funzione in questo modo:

 Module.debug = function () { var i, j, props, tmp; for (i = 0; i < arguments.length; i++) { tmp = this; props = arguments[i].split('.'); for (j = 0; j < props.length; j++) { tmp = tmp[props[j]]; } console.log(arguments[i] + ':', tmp); } }; 

Purtroppo, non riesco a trovare alcun modo per registrare in modo efficiente più variabili private che non sono membri di un object, ad esempio var roll = 3, value = 4; Module.debug.call(???); var roll = 3, value = 4; Module.debug.call(???);

Non è sicuro che tu possa ottenere direttamente ciò che vuoi da JavaScript, poiché il nome della variabile non viene portato in giro con il valore a cui fa riferimento (si pensi ai nomi di variabili come identificatori di cui solo il compilatore conosce, ma che vengono buttati via al runtime).

Tuttavia, è ansible fare qualcosa di leggermente diverso che consente di aggirare gli argomenti con nome. Crea un object anonimo e passa alla tua funzione:

 function showNames(o) { for( var ix in o ) { alert( ix + ":" + o[ix] ); } } var z = { x : "Anything" } showNames( z ); // or showNames( { a : "ay", b : "bee", c: "see" } ) 

Per iterare le proprietà dell’object, tendo a preferire uno stile funzionale, come in:

 Array.iteri = function(o, f) { for(var i in o) { f(i, o[i]) } } function showNames(o) { Array.iteri( o, function(i,v) { alert( i + ": " + v ) }); } showNames( { a : "ay", b : "bee", c: "see" } ) 

Il codice seguente è il meglio che puoi fare. Sfortunatamente le variabili locali in una funzione sono proprietà dell’object Chiamata nascosta, quindi non possono essere lette da Javascript come window [a] dove a è una proprietà dell’object window.

 x = "this is x"; var say = function(a) { document.write(a + " = " + window[a]); } say("x"); var wrapper = function () { var x = "this is x"; document.write(x + " = " + eval("x")) } wrapper()