2012-03-20 27 views
6

¿Hay alguna forma de obtener la variable con el nombre, como se puede hacer en .Net con reflejo?
como en este escenario:Obtener nombre de variable. javascript "reflection"

function(x,y,z) 
{ 
    if (x === 0) 
     logger.log('variable ' + x.reflectedName ' has invalid value ' + x) 
     // logs: 'variable x has invalid value 0) 
    ... 
} 

me encontré con preguntas similares que querían el nombre de la variable fuera de la función (?!) pero no pudo encontrar a esta pregunta.

(jQuery es una opción, aunque no puedo pensar en cómo se puede hacer con ella ...)

+7

Vale la pena señalar: no se puede obtener un nombre de variable a través de la reflexión en .NET. – StriplingWarrior

+0

@StriplingWarrior. puedes hacerlo con 'Expression'. Lo simplifico para ninguno .Net developers ... – gdoron

+1

¿por qué no solo registras tu nombre de variable en la cadena? en su ejemplo, sería igual de fácil poner x en la cadena 'console.log ('variable x tiene valor no válido:', x)' – SpYk3HH

Respuesta

7

Dado que está utilizando .NET como ejemplo, vamos a profundizar brevemente en eso. En C#, puede crear una función que toma un Expression:

void BadArgument<T>(Expression<Func<T>> argExpr) 
{ 
} 

Pero con el fin de ser capaz de extraer el nombre de variable de una llamada a esta función, usted tendría que asegurarse de que la llamada utiliza siempre exactamente la sintaxis correcta (a pesar de que no hay manera de hacer cumplir esta en tiempo de compilación):

if(x < 0) 
    BadArgument(() => x); 

por lo que se puede hacer, pero es muy frágil y bastante lento. Básicamente está generando instrucciones para crear un árbol de expresiones completo basado en la expresión lambda () => x, solo para que la función a la que llama pueda analizar ese árbol de expresiones e intentar encontrar el nombre del argumento.

¿Se puede hacer este tipo de cosas en javascript? ¡Por supuesto!

en JavaScript, cierres se producen a través de las funciones internas, por lo que el equivalente de la expresión lambda anterior sería:

function(){return x;} 

Y puesto que JavaScript es un lenguaje de script, cada función es el equivalente de su propia definición como una cadena. En otras palabras, llamando .toString() en la función anterior cederán:

function(){return x;} 

This jsfiddle shows cómo puede aprovechar esto en una función de estilo de registro. A continuación, puede analizar la cadena de funciones resultante, lo que será un poco más problemático que el análisis del .NET Expression Tree. Además, obtener el valor real de x es incluso más fácil que en .NET: ¡solo call the function!

Pero sólo porque usted puede do que no se debe significar. Es agradable como un truco de salón recórcholis, pero cuando se trata a fin de cuentas, no vale la pena:

  • Es frágil: ¿y si algún desarrollador no utiliza bien y le da una función que no puedes analizar?
  • No funciona con minimización: Imagínese tener un mensaje de esa variable a tenían un valor incorrecto debido a que su función minified cambió sus nombres de variables.
  • Se agrega sobrecarga: incluso un Minifier no puede acortar function(){return x;} a ser menor que "x".
  • Finalmente, es complicado. 'dijo nuff.
+0

** ¡Excelente! ** No lo usaré como sugirió, pero es una respuesta excelente ! Por cierto, ¿qué expresión regular usaría para sacar 'x' de' function() {return x;} '? – gdoron

+1

@gdoron: No sé si usaría expresiones regulares o no. Básicamente, solo quiere tomar todo después de "regresar" y antes de "}", y quitar cualquier espacio o punto y coma, y ​​decir una oración rápida para que el código de llamada no le arroje una bola curva. – StriplingWarrior

+0

** ¡Atención! ** tenga cuidado con 'minificación', cuando _minifique_ su nombre de variables de archivos * .js puede cambiar. @gdoron –

6

No se puede. Pero como ya conoce el nombre de la variable (ya que debe usarlo para concatenarlo hasta el final de la cadena), ¿por qué no simplemente escribirlo?

es decir .:

logger.log('variable x has invalid value '+x); 
+3

Creo que el ejemplo fue por simplicidad. Supongo que el OP quiere hacer esto para los casos en que el nombre de la variable no se conoce de antemano. Pero +1 por "No puedes". –

+0

¿Qué pasa si alguien llama a la función con sus propias variables: 'function (a, b, c)', 'x' no tendría sentido para ellos. –

+0

Sé que puedo codificar '' x' pero no quiero tot por mis propios motivos ... – gdoron

6

En realidad, usted CAN. Aquí hay un fragmento:

function getVarName(v) { 
    for (var key in window) { 
     if (window[key] === v) 
      return key; 
    } 
} 
var testvar = 13142; 
function test(t) { 
    var varName = getVarName(t); 
    // window[varName] -- your variable actualy 
    alert(varName); 
} 
test(testvar); // testvar 

El otro problema es si crea algunos vars que contengan la misma variable. Entonces se devolverá la primera var.

+5

'var testvar = 13142; var testvar2 = 13142;' o 'var testvar = true;' o cualquier cosa que sea un objeto arruinará su día. Cualquier cosa no definida en el alcance global de Windows también arruinará su día. –

-1

Es fácil de obtener el nombre de la variable

//This is variable you want to get the name 
var prop; 

var obj = {prop}; 
for(var propName in obj){ 
    alert(propName); 
    break; 
} 

también se puede tratar en .

+0

No creo que tenga la pregunta. Lee otras respuestas o la pregunta nuevamente. Gracias independientemente – gdoron

Cuestiones relacionadas