Nome da variável como uma string em Javascript

154

Existe uma maneira de obter um nome de variável como uma string em Javascript? (como NSStringFromSelectorno cacau )

Eu gostaria de fazer assim:

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

--> myFirstName:John

ATUALIZAR

Estou tentando conectar um navegador e outro programa usando JavaScript. Gostaria de enviar nomes de instâncias de um navegador para outro programa para o método de retorno de chamada:

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 outro programa:

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

No PHP: Como obter um nome de variável como uma string no PHP?

batata de peixe
fonte
2
@delnan De fato, +1. Não consigo pensar em outra maneira de dizer isso: "se você pode escrever variablesName(myFirstName), já sabe o nome da variável". Estou tentando, mas não posso ...
deceze
1
talvez para isso você possa armazenar em uma variável e posteriormente convertê-la em json, por exemplo {"instanceA": instanceA} e enviá-la ao servidor usando ajax ou get / post call e que você possa processar em php e obter o nome da instância ...
Geomorillo
@ deceze, claro, você sabe o nome, mas isso não significa que você pode / deseja digitá-lo manualmente. Talvez você queira despejar console.log("myvar = " + myvar);várias variáveis ​​para fins de depuração e não sinta vontade de digitar manualmente repetidamente, para cada variável.
Synetech 6/10/19

Respostas:

54

Normalmente, você usaria uma tabela de hash para uma situação em que deseja mapear um nome para algum valor e conseguir recuperar os dois.

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

karim79
fonte
125
Mas não responde à pergunta.
Htafoya #
1
@ htafoya: Indiretamente, sim - todas as propriedades de objsão impressas como name: valuepares. Mas o texto explicativo pode ser mais claro.
Matt
1
@ Mat Eu entendo o código, mas geralmente a questão OP é usada para algo mais complexo como atribuições dinâmicas, onde você pode selecionar a variável de uma string gerada. Ou onde simplesmente criar um dicionário para imprimir um valor é um exagero.
Htafoya #
2
@ htafoya - sim, algo simples como nameof (varname) em C #.
20518 Matt
1
Eu acho que a única razão pela qual isso "não responde à pergunta" é porque não começa com "Você não pode obter o nome da constante ou variável em JavaScript. A coisa mais próxima do que você deseja ...", como esta outra resposta: stackoverflow.com/a/37393679
bigpopakap
86

Como a resposta de Seth, mas usa Object.keys():

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

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

Donuts
fonte
5
@titusfx você pode trocar const por let ou var e funciona da mesma forma. Mas se você estiver usando um transpiler para a destruição do objeto em primeiro lugar, provavelmente ele já suporta const.
SethWhite
Isso parece depender do uso do ES6?
O'Rooney
1
@ O'Rooney Sim, é específico do ES6.
Donuts
63

Você pode usar a seguinte solução para resolver seu problema:

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

// returns "myFirstName"
Estrangeiro companheiro
fonte
3
Esta resposta é semelhante a [@ SethWhite] ( stackoverflow.com/a/39669231/5876282 ), mas muito simplificada. Obrigado! @bluejayke Acho que essa resposta vem anos depois da resposta original aceita. Mas sim, atualmente este é o melhor - exceto, talvez, o "pop ()" Uso sugerido abaixo
B Charles H
1
é possível criar uma função que aceite variável e imprima seu nome? Eu tentei quebrar seu código dentro de uma função, mas id me retornou o nome que foi usado como argumento
Wakan Tanka 27/02
@WakanTanka Se você criar uma pergunta adequada, eu responderei lá.
Estrangeiro,
@WakanTanka não, isso não funcionaria. Como você descobriu, ele imprimirá apenas o nome que você deu ao argumento da função. Eu acho que ajuda ver como essa função seria compilada para uma especificação Javascript mais antiga. Você pode ver neste exemplo ( jsfiddle.net/bigpopakap/wq891ghr/2 ) que a sintaxe {variable} é apenas uma abreviação de {variable: variable}; portanto, é impossível usar o nome da variável na função de chamada
bigpopakap
42

No ES6, você poderia escrever algo como:

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

Não é realmente a coisa mais bonita, mas faz o trabalho.

Isso aproveita a destruição de objetos do ES6.

Mais informações aqui: https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/

SethWhite
fonte
1
Ótima resposta!! Este uso particular de objeto destructing é novo para mim (linha 2 let nameObject = {myVar}tão útil Ele não parece ser documentado em qualquer lugar Tem alguma links!.?
Laurence Senhor
2
@LaurenceLord é chamado de abreviação de propriedade. Atribuir uma propriedade de objeto sem uma definição (algo: 'asdf') fará com que JS defina a propriedade com o nome da variável e seu valor {something} === {something: something}. ariya.io/2013/02/…
SethWhite
19
var x = 2;
for(o in window){ 
   if(window[o] === x){
      alert(o);
   }
}

No entanto, acho que você deveria gostar de "karim79"

trevo
fonte
8
Isso funcionará apenas no escopo da janela (quebras quando estiver dentro de uma função).
jpillora
1
Concordou - mas é o mais próximo de responder à pergunta do OP. Gj.
O Dembinski
Além disso, se você estiver testando uma primitiva, ela alertará todas as variáveis ​​que têm o mesmo valor ou se duas variáveis ​​tiverem o mesmo objeto atribuído a elas. Por exemplo, se a primeira linha foi x = 2; y = 2;ou x = {a:1}; b = x;seria alertar cada um deles
aljgom
Se você quer este trabalho em um escopo de função você pode tentar usar o nome da função em vez da janela, como: var foo = function f(){ f.x = 2; for(o in f){ if(f[o]===f.x) alert(o); } }em seguida, chamar f()alerta vontade 'x'
aljgom
1
@aljgom - bom ponto. Aqui está um violino para experimentá-lo.
20918 Matt
16

Isso funciona para expressões básicas

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

Exemplo

nameof(() => options.displaySize);

Snippet:

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

BrunoLM
fonte
2
Isso realmente funciona muito bem! o único problema é quando você passa algo assim: nameof (() => options.subOptions.displaySize) que retorna "subOptions" Em vez disso, usei esse regex: exp.toString (). match (/ (? = [^ .] * $) (\ w +) / g) [0]
Jim Brown
Fico indefinido de: var a = {b: "c"}; alerta (nome (a)); nome da função (exp) {exp.toString (). match (/ (? = [^.] * $) (\ w +) / g) [0]; } // nome
David Spector
@JimBrown, obrigado! seu comentário precisa marcar como resposta!
evorios
14

Provavelmente pop seria melhor do que indexar com [0], por segurança (a variável pode 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
fonte
3
Se myFirstName for passado para uma função (contendo esse código) como argumento v, variableName será relatado como v em vez de myFirstName.
David Spector
9
var somefancyvariable = "fancy";
Object.keys({somefancyvariable})[0];

Isso não pode ser transformado em uma função, pois retorna o nome da variável da função.

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

Edit: Obrigado ao @Madeo por apontar como transformar isso em uma função .

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

Você precisará chamar a função com uma matriz de elemento único contendo a variável. debugVar({somefancyvariable});
Edit: Object.keyspode ser referenciado como keysem todos os navegadores em que o testei, mas de acordo com os comentários, ele não funciona em todos os lugares.

Cadiboo
fonte
Erro: "Não foi possível encontrar as chaves variáveis"
Alexander Volkov
chaves não está definido
avalanche1
1
deve ser assim const getVarName = (v) => Object.keys(v)[0];e então chamar a função assimgetVarName({whatEverVariable})
Madeo
6

Desde o ECMAScript 5.1, você pode usar Object.keys para obter os nomes de todas as propriedades de um objeto.

Aqui está um exemplo:

// 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
fonte
4

Ao ter uma função, escreva uma função que altere diferentes valores de variáveis ​​globais, nem sempre é meu primeiro nome; é o que quer que esteja passando. Tente isso funcionou para mim.

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

Irá escrever na janela 'jack'.

Matt smith
fonte
2
Isso não é confiável. Pode haver qualquer número de variáveis ​​no objeto de janela com o mesmo valor.
Taylor Buchanan /
2

Você pode refletir sobre os tipos em javascript e obter o nome das propriedades e métodos, mas o que você precisa é sth como Lambda Expressions Treesno .NET, acho que não é possível devido à natureza dinâmica e à falta de sistema de tipo estático em javascript.

Jahan
fonte
3
Eu não acho que JS fica aquém das lambdas ou ferramentas relacionadas de programação funcional.
Mas acho que não existe uma estrutura equivalente às Expression Trees no .NET.
Jahan
2

Eu precisava disso, não quero usar objetos e vim com a seguinte solução, revertendo a questão.

Em vez de converter o nome da variável em uma sequência, eu converto uma sequência em uma variável.

Isso só funciona se o nome da variável for conhecido, é claro.

Pegue isso:

var height = 120;
testAlert(height);

Isso deve exibir:

height: 120

Isso pode ser feito assim:

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

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

Então eu uso a string "height"e a transformo em uma variável heightusando o window[]comando

SPRBRN
fonte
2
No seu segundo caso, height é uma propriedade do windowobjeto porque a variável de mesmo nome foi declarada no escopo da janela. Isso funciona apenas se a variável for declarada no escopo da janela, não em uma função / fechamento.
Xoxox
2

Shorts maneira que eu encontrei até agora para obter o nome das variáveis ​​como uma string:

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
fonte
1

Isso funcionou usando o Internet Explorer (9, 10 e 11), Google Chrome 5:

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

Tabela de compatibilidade do navegador:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

danilo
fonte
Google Chrome 5? realmente??
avalanche1
2
@ avalanche1, de acordo com a tabela de compatibilidade de versões do MDN.
11119 danilo
0

Eu criei essa função com base no JSON, como alguém sugeriu, funciona bem para minhas necessidades de depuração

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
fonte
-3

Não, não há.
Além disso, se você pode escrever variablesName(myFirstName), já sabe o nome da variável ("myFirstName").

deceze
fonte
11
Não necessariamente verdadeiro se o código está sendo minified;)
Segredo
9
Além disso, o objetivo de usar, por exemplo, nameof(myVariable)em C # (que retorna uma string "myVariable", é proteger contra erros ao refatorar ou fazer outras alterações no código. Um caso de uso comum é adicionar o nome da variável a uma mensagem de erro sendo lançada. a maioria das peças que eu considero seqüência literais um cheiro de código, e suspeito que é por isso que, pelo menos, Visual Studio, mostra em uma cor / laranja vermelha eu sei eu sei, esta questão é sobre Javascript, mas eu acabei de explicar por que eu acabei aqui..
merrr 28/01
teste var = 1235125142; console.log (Object.keys ({test}). pop ()) // "test"
bluejayke
1
@bluejayke Me chame de ignorante, mas depois de 8 anos eu ainda não vejo como isso é melhor do que console.log('test')ou quando você realmente precisa disso.
deceze