Nombre de variable como una cadena en Javascript

154

¿Hay alguna manera de obtener un nombre de variable como una cadena en Javascript? (como NSStringFromSelectoren cacao )

Me gustaría hacer así:

var myFirstName = 'John';
alert(variablesName(myFirstName) + ":" + myFirstName);

--> myFirstName:John

ACTUALIZAR

Estoy tratando de conectar un navegador y otro programa usando JavaScript. Me gustaría enviar nombres de instancia desde un navegador a otro programa para el método de devolución de llamada:

FooClass = function(){};
FooClass.someMethod = function(json) {
  // Do something
}

instanceA = new FooClass();
instanceB = new FooClass();
doSomethingInAnotherProcess(instanceB); // result will be substituted by using instanceB.someMethod();

...

De otro programa:

evaluateJavascriptInBrowser("(instanceName).someMethod("resultA");");

En PHP: ¿Cómo obtener un nombre de variable como una cadena en PHP?

papa de pescado
fuente
2
@delnan De hecho, +1. No puedo pensar en otra forma de decirlo que "si puedes escribir variablesName(myFirstName), ya conoces el nombre de la variable". Estoy intentando, pero no puedo ...
deceze
1
tal vez para eso podría almacenarlo en una variable y luego convertirlo a json, por ejemplo {"instanciaA": instanciaA} y enviarlo al servidor usando ajax o get / post call y que pueda procesar en php y obtener el nombre de la instancia ...
Geomorillo
@deceze, seguro, conoces el nombre, pero eso no significa que puedas / quieras escribirlo manualmente. Tal vez desee volcar un montón de variables con fines de depuración y no tenga ganas de escribir manualmente console.log("myvar = " + myvar);una y otra vez, para cada variable.
Synetech

Respuestas:

54

Por lo general, usaría una tabla hash para una situación en la que desea asignar un nombre a algún valor y poder recuperar ambos.

var obj = { myFirstName: 'John' };
obj.foo = 'Another name';
for(key in obj)
    console.log(key + ': ' + obj[key]);

karim79
fuente
125
Sin embargo, no responde la pregunta.
htafoya
1
@htafoya: Indirectamente, sí, todas las propiedades de objse imprimen como name: valuepares. Pero el texto explicativo podría ser más claro.
Matt
1
@Mat Entiendo el código, pero generalmente la pregunta OP se usa para algo más complejo como asignaciones dinámicas donde puede seleccionar la variable de una cadena generada. O donde simplemente crear un diccionario para imprimir un valor es excesivo.
htafoya
2
@htafoya: sí, algo simple como nameof (varname) en C #.
Matt
1
Creo que la única razón por la que este "no responde la pregunta" es porque no comienza con "No se puede obtener el nombre de la constante o una variable en JavaScript. Lo más parecido a lo que quieres ...", como esta otra respuesta: stackoverflow.com/a/37393679
bigpopakap
86

Como la respuesta de Seth, pero usa en su Object.keys()lugar:

const varToString = varObj => Object.keys(varObj)[0]

const someVar = 42
const displayName = varToString({ someVar })
console.log(displayName)

Rosquillas
fuente
55
@titusfx puedes cambiar const por let o var y funciona igual. Pero si está utilizando un transpilador para la desestructuración de objetos en primer lugar, probablemente ya sea compatible con const.
SethWhite
Esto parece depender del uso de ES6?
O'Rooney
1
@ O'Rooney Sí, es ES6 específico.
Donuts
63

Puede usar la siguiente solución para resolver su problema:

const myFirstName = 'John'
Object.keys({myFirstName})[0]

// returns "myFirstName"
Extraño compañero
fuente
3
Esta respuesta es similar a [@ SethWhite's] ( stackoverflow.com/a/39669231/5876282 ) pero muy simplificada. ¡Gracias! @bluejayke Creo que esta respuesta llega años después de la respuesta original aceptada. Pero sí, actualmente este es el mejor, excepto quizás el uso "pop ()" sugerido a continuación
B Charles H
1
¿Es posible hacer una función que acepte variables e imprima su nombre? Intenté envolver su código dentro de una función, pero la identificación me devolvió el nombre que se utilizó como argumento
Wakan Tanka
@WakanTanka Si crea una pregunta adecuada, la responderé allí.
Compañero extraño
@WakanTanka no, eso no funcionaría. Como descubrió, simplemente imprimirá el nombre que le dé al argumento de la función. Creo que ayuda ver cómo tal función se compilaría con una especificación Javascript más antigua. Puede ver en este ejemplo ( jsfiddle.net/bigpopakap/wq891ghr/2 ) que la sintaxis {variable} es la abreviatura de {variable: variable}, por lo que es imposible usar el nombre de la variable de la función de llamada
bigpopakap
42

En ES6, podría escribir algo como:

let myVar = 'something';
let nameObject = {myVar};
let getVarNameFromObject = (nameObject) => {
  for(let varName in nameObject) {
    return varName;
  }
}
let varName = getVarNameFromObject(nameObject);

Realmente no es lo mejor, pero hace el trabajo.

Esto aprovecha la desestructuración de objetos de ES6.

Más información aquí: https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/

SethBlanco
fuente
1
¡¡Gran respuesta!! Este uso particular de la destrucción de objetos es nuevo para mí (¡la línea 2 es let nameObject = {myVar}muy útil! No parece estar documentada en ninguna parte. ¿Tienes algún enlace?)
Laurence Lord
2
@LaurenceLord se llama propiedad abreviada. Asignar una propiedad de objeto sin una definición (algo: 'asdf'), hará que JS defina la propiedad con el nombre de la variable y su valor {something} === {something: something}. ariya.io/2013/02/…
SethWhite
19
var x = 2;
for(o in window){ 
   if(window[o] === x){
      alert(o);
   }
}

Sin embargo, creo que deberías hacer como "karim79"

trébol
fuente
8
Esto solo funcionará en el ámbito de la ventana (se rompe cuando está dentro de una función).
jpillora
1
De acuerdo, pero es lo más cercano a responder la pregunta del OP. Gj.
The Dembinski
Además, si está probando una primitiva, alertará a todas las variables que tienen el mismo valor, o si dos variables tienen el mismo objeto asignado. Por ejemplo, si la primera línea era x = 2; y = 2;o x = {a:1}; b = x;alertaría a cada uno de ellos
aljgom
Si desea que esto funcione en un ámbito de función , puede intentar usar el nombre de la función en lugar de la ventana, como: var foo = function f(){ f.x = 2; for(o in f){ if(f[o]===f.x) alert(o); } }luego, la llamada f()alertará 'x'
aljgom
1
@aljgom - buen punto. Aquí hay un violín para probarlo.
Matt
16

Esto funciona para expresiones básicas

const nameof = exp => exp.toString().match(/[.](\w+)/)[1];

Ejemplo

nameof(() => options.displaySize);

Retazo:

var nameof = function (exp) { return exp.toString().match(/[.](\w+)/)[1]; };
var myFirstName = 'Chuck';
var varname = nameof(function () { return window.myFirstName; });
console.log(varname);

BrunoLM
fuente
2
¡Esto realmente funciona bastante bien! el único problema es cuando pasas algo como esto: nameof (() => options.subOptions.displaySize) que devuelve "subOptions" En su lugar, utilicé esta expresión regular: exp.toString (). match (/ (? = [^ .] * $) (\ w +) / g) [0]
Jim Brown el
Tengo indefinido de: var a = {b: "c"}; alerta (nombre (a)); nombre de función (exp) {exp.toString (). match (/ (? = [^.] * $) (\ w +) / g) [0]; } // nombre
David Spector
@ JimBrown, gracias! su comentario debe marcar como respuesta!
evorios
14

Probablemente pop sería mejor que indexar con [0], por seguridad (la variable puede ser nula).

const myFirstName = 'John'
const variableName = Object.keys({myFirstName}).pop();
console.log(`Variable ${variableName} with value '${variable}'`);

// returns "Variable myFirstName with value 'John'"
Juangui Jordán
fuente
3
Si myFirstName se pasa a una función (que contiene este código) como argumento v, entonces variableName se informa como v en lugar de myFirstName.
David Spector
9
var somefancyvariable = "fancy";
Object.keys({somefancyvariable})[0];

Esto no se puede convertir en una función, ya que devuelve el nombre de la variable de la función.

// THIS DOESN'T WORK
function getVarName(v) {
    return Object.keys({v})[0];
}
// Returns "v"

Editar: Gracias a @Madeo por señalar cómo convertir esto en una función .

function debugVar(varObj) {
    var varName = Object.keys(varObj)[0];
    console.log("Var \"" + varName + "\" has a value of \"" + varObj[varName] + "\"");
}

Necesitará llamar a la función con una matriz de elementos únicos que contenga la variable. debugVar({somefancyvariable});
Editar: se Object.keyspuede hacer referencia como solo keysen cada navegador en el que lo probé, pero de acuerdo con los comentarios, no funciona en todas partes.

Cadiboo
fuente
Error: "No se pueden encontrar claves variables"
Alexander Volkov
las claves no están definidas
avalanche1
1
debería ser así const getVarName = (v) => Object.keys(v)[0];y luego llamar a la función asígetVarName({whatEverVariable})
Madeo
6

Desde ECMAScript 5.1 puede usar Object.keys para obtener los nombres de todas las propiedades de un objeto.

Aquí hay un ejemplo:

// Get John’s properties (firstName, lastName)
var john = {firstName: 'John', lastName: 'Doe'};
var properties = Object.keys(john);

// Show John’s properties
var message = 'John’s properties are: ' + properties.join(', ');
document.write(message);

Benny Neugebauer
fuente
4

Al tener una función, escriba una función que cambie los valores de diferentes variables globales, no siempre es mi nombre, es lo que sea que esté pasando. Prueba esto funcionó para mí.

Ejecutar en jsfiddle

var jack = 'jill';
function window_getVarName(what)
{
  for (var name in window)
  {
    if (window[name]==what)
    return(name);
  }
  return("");
}
document.write(window_getVarName(jack));

Escribirá a la ventana 'jack'.

Matt Smith
fuente
2
Esto no es confiable. Podría haber cualquier número de variables en el objeto de ventana con el mismo valor.
Taylor Buchanan
2

Puede reflexionar sobre los tipos en JavaScript y obtener el nombre de las propiedades y los métodos, pero lo que necesita es algo como Lambda Expressions Treesen .NET, creo que no es posible debido a la naturaleza dinámica y la falta de un sistema de tipo estático en JavaScript.

Jahan
fuente
3
No creo que JS se quede corto de lambdas o herramientas relacionadas de programación funcional.
Pero creo que no hay una estructura equivalente a los árboles de expresión en .NET.
Jahan
2

Necesitaba esto, no quiero usar objetos, y se me ocurrió la siguiente solución, dando vuelta la pregunta.

En lugar de convertir el nombre de la variable en una cadena, convierto una cadena en una variable.

Esto solo funciona si se conoce el nombre de la variable, por supuesto.

Toma esto:

var height = 120;
testAlert(height);

Esto debería mostrar:

height: 120

Esto se puede hacer así:

function testAlert(ta)
{
    a = window[ta];
    alert(ta + ': ' + a); 
}

var height = 120;
testAlert("height");
// displays: height: 120

Entonces uso la cadena "height"y la convierto en una variable heightusando el window[]comando.

SPRBRN
fuente
2
En su segundo caso, la altura es una propiedad del windowobjeto porque la variable del mismo nombre se declaró en el ámbito de la ventana. Esto funciona solo si la variable se declara en el ámbito de la ventana, no en una función / cierre.
xoxox
2

El camino corto que he encontrado hasta ahora para obtener el nombre de las variables como una cadena:

const name = obj => Object.keys(obj)[0];

const whatsMyName = "Snoop Doggy Dogg";

console.log( "Variable name is: " + name({ whatsMyName }) );
//result: Variable name is: whatsMyName

Sebastian Knopp
fuente
1

Esto funcionó con Internet Explorer (9, 10 y 11), Google Chrome 5:

   
var myFirstName = "Danilo";
var varName = Object.keys({myFirstName:0})[0];
console.log(varName);

Tabla de compatibilidad del navegador:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

danilo
fuente
Google Chrome 5? ¿¿De Verdad??
avalanche1
2
@ avalanche1, de acuerdo con la tabla de compatibilidad de versiones de MDN.
danilo
0

He creado esta función basada en JSON como alguien sugirió, funciona bien para mis necesidades de depuración

function debugVar(varNames){
let strX = "";
function replacer(key, value){
    if (value === undefined){return "undef"}
    return value
    }    
for (let arg of arguments){
let lastChar;
    if (typeof arg!== "string"){
        let _arg = JSON.stringify(arg, replacer);
        _arg = _arg.replace('{',"");
        _arg = _arg.replace('}',"");            
        _arg = _arg.replace(/:/g,"=");
        _arg = _arg.replace(/"/g,"");
        strX+=_arg;
    }else{
    strX+=arg;
    lastChar = arg[arg.length-1];
    }
    if (arg!==arguments[arguments.length-1]&&lastChar!==":"){strX+=" "};
}
console.log(strX)    
}
let a = 42, b = 3, c;
debugVar("Begin:",{a,b,c},"end")

Igor Fomenko
fuente
-3

No no hay.
Además, si puede escribir variablesName(myFirstName), ya conoce el nombre de la variable ("myFirstName").

difunto
fuente
11
No necesariamente es cierto si el código se está minimizando;)
Secreto
9
También el punto de usar, por ejemplo, nameof(myVariable)en C # (que devuelve una cadena "myVariable" es proteger contra errores al refactorizar o realizar otros cambios en el código. Un caso de uso común es agregar el nombre de la variable a un mensaje de error que se lanza. la mayor parte considero literales de cadena un olor código, y sospecha que es por lo menos de Visual Studio, los muestra en un color / rojo anaranjado que sé que sé, esta pregunta se trata de Javascript, pero me acaba de explicar por qué terminé aquí..
merrr
prueba var = 1235125142; console.log (Object.keys ({prueba}). pop ()) // "prueba"
bluejayke
1
@bluejayke Llámame ignorante, pero después de 8 años todavía no veo cómo eso es mejor console.log('test')o cuándo realmente lo necesitarías.
Fallecimiento