2010-08-04 11 views
20

Tengo la sensación de que esto podría no ser posible, pero me gustaría determinar el nombre de la variable original que se ha pasado a una función en javascript. No sé cómo explicarlo mejor que eso, así que mira si este ejemplo tiene sentido.Determinar el nombre original de la variable después de pasarla a una función

function getVariableName(unknownVariable){ 
    return unknownVariable.originalName; 
} 

getVariableName(foo); //returns string "foo"; 
getVariableName(bar); //returns string "bar"; 

Este es un plugin de jQuery que estoy trabajando, y me gustaría ser capaz de mostrar el nombre de la variable que se pasa a una función de "depuración".

+1

No estoy seguro de cuál es el propósito de esto, ya que necesitaría interesarse en los valores de las variables que el nombre de la variable. –

+2

No hay nombres de variable cuando se ejecuta un programa. No "actuales", y no "originales". – Tomalak

+1

Jaja, pensé que esto era un tiro largo, pero vale la pena intentarlo. No hay demasiado propósito, pero si quiere contexto, puede ver la versión actual del complemento: http://andygroff.com/jquery-debugger-debugging-plugin/ Si ve el ejemplo del objeto, lo haría prefiero que el título diga "Propiedades de la empresa de ropa" en lugar de simplemente "Propiedades del objeto". No es terriblemente importante, pero sería bueno. –

Respuesta

17

Tienes razón, esto es muy imposible de una manera sensata, ya que solo el valor pasa a la función.

+7

¿cuál es la manera insana? –

+9

Obtenga una traza inversa, obtenga el número de archivo y de línea de la invocación de función, cargue el código fuente de ese archivo, encuentre y analice esa línea, intente averiguar qué variable era su parámetro. Dado que puede haber varias llamadas a función en una línea y funciones con un alias en tiempo de ejecución, por no mencionar la complejidad de la tarea, espero que la locura de esto sea evidente. – deceze

+0

Esto es ahora algo posible, ver mi respuesta. – Offirmo

1

Aquí hay una técnica que puede usar para mantener el nombre y el valor de la variable.

// Set up a global variable called g 
var g = {}; 
// All other variables should be defined as properties of this global object 
g.foo = 'hello'; 
g.bar = 'world'; 

// Setup function 
function doStuff(str) { 
    if (str in g) { 
    var name = str; 
    var value = g[str]; 
    // Do stuff with the variable name and the variable value here 
    // For this example, simply print to console 
    console.log(name, value); 
    } else { 
    console.error('Oh snap! That variable does not exist!'); 
    } 
} 

// Call the function 
doStuff('foo'); // log: foo hello 
doStuff('bar'); // log: bar world 
doStuff('fakeVariable'); // error: Oh snap! That variable does not exist! 

Esto está efectivamente creando un diccionario que asigna nombres de variables a su valor. Probablemente esto no funcionará para su código existente sin refactorizar cada variable. Pero al usar este estilo, puede lograr una solución para este tipo de problema.

+0

Gracias por la respuesta. Esta es una buena solución, aunque realmente no resuelve el problema que tuve. Estaba escribiendo un complemento de depuración que crearía una alerta modal con información sobre variables, incluido su nombre. Tendría que ejecutarse con cualquier javascript, por lo que almacenar todas las variables como propiedades del objeto no es una solución viable. ¡Gracias! –

+0

@AndyGroff sustituyendo la variable 'g' por la variable' window' podría resolver su problema. Pero, en última instancia, tendrá que acceder a las variables por cadena en lugar del identificador. – styfle

1

Bueno, todas las variables globales son propiedades del objeto global (esta o ventana), ¿no es así? Así que cuando quería averiguar el nombre de mi variables, hice siguiente función:

var getName = function(variable) { 
    for (var prop in window) { 
    if (variable === window[prop]) { 
     return prop; 
    } 
    } 
} 
var helloWorld = "Hello World!"; 
console.log(getName(helloWorld)); // "helloWorld" 

A veces no funciona, por ejemplo, si se crean 2 cadenas sin nuevo operador y tienen el mismo valor.

+0

¿Esto depende de que se ejecute en el navegador? ¿O no entiendo qué es 'window'? – byxor

+1

Esto no funcionará si dos objetos tienen el mismo valor. 'window.a = 1; window.b = 1;' Devolverá el nombre del primer valor coincidente. Además, es una mala práctica definir variables en el alcance global. – styfle

0

la conversión de un conjunto de variables única en un objeto JSON para que escribí esta función

function makeJSON(){ //Pass the variable names as string parameters [not by reference] 
ret={}; 
for(i=0; i<arguments.length; i++){ 
    eval("ret."+arguments[i]+"="+arguments[i]); 
} 
return ret; 
} 

Ejemplo:

a=b=c=3; 
console.log(makeJSON('a','b','c')); 

Quizás esta es la razón para esta consulta

+5

'ret [x] = x'; ¡absolutamente ninguna razón para 'eval' aquí! – deceze

1

Este es ahora de alguna manera posible gracias a ES6:

function getVariableName(unknownVariableInAHash){ 
 
    return Object.keys(unknownVariableInAHash)[0] 
 
} 
 

 
const foo = 42 
 
const bar = 'baz' 
 
console.log(getVariableName({foo})) //returns string "foo" 
 
console.log(getVariableName({bar})) //returns string "bar"

La única (pequeña) problema es que hay que envolver la variable desconocida entre {}, que no es gran cosa.

+1

'{foo}' es simplemente '{foo: 42}' ... así que lo estás enviando como un objeto. Consulte 'Nuevas anotaciones en ECMAScript 2015': https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer –

+0

@CodyG. Estoy perfectamente enterado de eso. – Offirmo

+1

Entonces no deberías decir "de alguna manera posible gracias a es6", tu respuesta es básicamente --- 'puedes hacerlo enviando el valor como un objeto con la clave como el nombre de la variable' ... que también se puede hacer fácilmente en es5 con un polyfill de Object.keys, o simplemente pasando un objeto con el nombre de la variable como otra propiedad. –

Cuestiones relacionadas