Nom de variable sous forme de chaîne en Javascript


154

Existe-t-il un moyen d'obtenir un nom de variable sous forme de chaîne en Javascript? (comme NSStringFromSelectordans Cocoa )

Je voudrais faire comme ceci:

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

--> myFirstName:John

METTRE À JOUR

J'essaye de connecter un navigateur et un autre programme en utilisant JavaScript. Je voudrais envoyer des noms d'instance d'un navigateur à un autre programme pour la méthode de rappel:

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

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

...

Depuis un autre programme:

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

En PHP: Comment obtenir un nom de variable sous forme de chaîne en PHP?


2
@delnan En effet, +1. Je ne peux pas penser à une autre façon de le dire que «si vous pouvez écrire variablesName(myFirstName), vous connaissez déjà le nom de la variable».
J'essaye


1
peut-être pour cela vous pourriez stocker dans une variable et la convertir plus tard en json par exemple {"instanceA": instanceA} et l'envoyer au serveur en utilisant ajax ou get / post call et que vous pouvez traiter en php et obtenir le nom de l'instance ...
Geomorillo

@deceze, bien sûr, vous connaissez le nom, mais cela ne signifie pas que vous pouvez / voulez le saisir manuellement. Peut-être que vous voulez vider un tas de variables à des fins de débogage et que vous n'avez pas envie de taper manuellement console.log("myvar = " + myvar);encore et encore, pour chaque variable.
Synetech

Réponses:


54

En règle générale, vous utilisez une table de hachage pour une situation dans laquelle vous souhaitez mapper un nom sur une valeur et être en mesure de récupérer les deux.

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


127
Mais ne répond pas à la question.
htafoya

1
@htafoya: Indirectement, oui - toutes les propriétés de objsont imprimées par name: valuepaires. Mais le texte explicatif pourrait être plus clair.
Matt

1
@Mat Je comprends le code, mais généralement la question OP est utilisée pour quelque chose de plus complexe que les assignations dynamiques où vous pouvez sélectionner la variable à partir d'une chaîne générée. Ou où simplement créer un dictionnaire pour imprimer une valeur est exagéré.
htafoya

2
@htafoya - oui, quelque chose de simple comme nameof (varname) en C #.
mat

1
Je pense que la seule raison pour laquelle "ne répond pas à la question" est que cela ne commence pas par "Vous ne pouvez pas obtenir le nom de la constante ou d'une variable en JavaScript. La chose la plus proche de ce que vous voulez ...", comme cette autre réponse: stackoverflow.com/a/37393679
bigpopakap

86

Comme la réponse de Seth, mais utilise à la Object.keys()place:

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

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


5
@titusfx vous pouvez remplacer const par let ou var et cela fonctionne de la même manière. Mais si vous utilisez un transpilateur pour la déstructuration d'objet en premier lieu, il prend probablement déjà en charge const.
SethWhite

Cela semble dépendre de l'utilisation d'ES6?
O'Rooney

1
@ O'Rooney Oui, c'est spécifique à ES6.
Donuts

64

Vous pouvez utiliser la solution suivante pour résoudre votre problème:

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

// returns "myFirstName"

3
Cette réponse est similaire à [@ SethWhite's] ( stackoverflow.com/a/39669231/5876282 ) mais beaucoup simplifiée. Merci! @bluejayke Je pense que cette réponse vient des années plus tard après la réponse initiale acceptée. Mais oui, c'est actuellement le meilleur - sauf peut-être l'utilisation de "pop ()" suggérée ci
B Charles H

1
est-il possible de créer une fonction qui acceptera la variable et affichera son nom? J'ai essayé d'envelopper votre code dans une fonction mais l'id m'a renvoyé le nom qui a été utilisé comme argument
Wakan Tanka

@WakanTanka Si vous créez une bonne question, je vais y répondre.
Fellow Stranger

@WakanTanka non, cela ne fonctionnerait pas. Comme vous l'avez découvert, il affichera simplement le nom que vous donnez à l'argument de fonction. Je pense que cela aide de voir comment une telle fonction se compilerait avec une spécification Javascript plus ancienne. Vous pouvez voir dans cet exemple ( jsfiddle.net/bigpopakap/wq891ghr/2 ) que la syntaxe {variable} est simplement courte pour {variable: variable}, il est donc impossible d'utiliser le nom de la variable de la fonction appelante
bigpopakap

42

Dans ES6, vous pouvez écrire quelque chose comme:

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

Pas vraiment la plus belle chose, mais elle fait le travail.

Cela exploite la déstructuration des objets d'ES6.

Plus d'informations ici: https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/


1
Très bonne réponse!! Cette utilisation particulière de la destruction d'objets est nouvelle pour moi (ligne 2 let nameObject = {myVar}si utile! Elle ne semble être documentée nulle part. Vous avez des liens?
Laurence Lord

2
@LaurenceLord c'est ce qu'on appelle le raccourci de propriété. Assigner une propriété d'objet sans définition (quelque chose: 'asdf'), obligera JS à définir la propriété avec le nom de la variable et sa valeur {quelque chose} === {quelque chose: quelque chose}. ariya.io/2013/02/…
SethWhite

19
var x = 2;
for(o in window){ 
   if(window[o] === x){
      alert(o);
   }
}

Cependant, je pense que vous devriez faire comme "karim79"


8
Cela ne fonctionnera qu'à la portée de la fenêtre (se casse à l'intérieur d'une fonction).
jpillora du

1
D'accord - mais c'est le plus proche de répondre à la question du PO. Gj.
The Dembinski

également si vous testez une primitive, elle alertera toutes les variables qui ont la même valeur, ou si deux variables ont le même objet qui leur est assigné. Par exemple , si la première ligne était x = 2; y = 2;ou x = {a:1}; b = x;il alerter chacun d'eux
aljgom

Si vous voulez que cela fonctionne dans une portée de fonction, vous pouvez essayer d'utiliser le nom de la fonction au lieu de window, comme: var foo = function f(){ f.x = 2; for(o in f){ if(f[o]===f.x) alert(o); } }alors l'appel f()va alerter 'x'
aljgom

1
@aljgom - bon point. Voici un violon pour l'essayer.
Matt

16

Cela fonctionne pour les expressions de base

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

Exemple

nameof(() => options.displaySize);

Fragment:

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


2
Cela fonctionne plutôt bien! le seul problème est lorsque vous passez quelque chose comme ceci: nameof (() => options.subOptions.displaySize) qui renvoie "subOptions" Au lieu de cela, j'ai utilisé cette expression régulière: exp.toString (). match (/ (? = [^ .] * $) (\ w +) / g) [0]
Jim Brown

Je reçois indéfini de: var a = {b: "c"}; alert (nom (a)); nom de la fonction (exp) {exp.toString (). match (/ (? = [^.] * $) (\ w +) / g) [0]; } // nom
David Spector

@JimBrown, merci! votre commentaire doit être marqué comme réponse!
evorios

14

Pop serait probablement mieux que l'indexation avec [0], pour des raisons de sécurité (la variable peut être nulle).

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

// returns "Variable myFirstName with value 'John'"

3
Si myFirstName est passé à une fonction (contenant ce code) comme argument v, alors variableName est signalé comme v au lieu de myFirstName.
David Spector

9
var somefancyvariable = "fancy";
Object.keys({somefancyvariable})[0];

Cela ne peut pas être transformé en fonction car il renvoie le nom de la variable de la fonction.

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

Edit: Merci à @Madeo pour avoir indiqué comment en faire une fonction .

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

Vous devrez appeler la fonction avec un seul tableau d'éléments contenant la variable. debugVar({somefancyvariable});
Edit: Object.keyspeut être référencé comme keysdans tous les navigateurs dans lesquels je l'ai testé, mais selon les commentaires, cela ne fonctionne pas partout.


Erreur: "Impossible de trouver les clés variables"
Alexander Volkov

clés n'est pas définie
avalanche1

1
ça devrait être comme ça const getVarName = (v) => Object.keys(v)[0];, puis appelez la fonction comme çagetVarName({whatEverVariable})
Madeo

6

Depuis ECMAScript 5.1, vous pouvez utiliser Object.keys pour obtenir les noms de toutes les propriétés d'un objet.

Voici un exemple:

// 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);


4

Lorsqu'une fonction écrit une fonction qui change les valeurs de différentes variables globales, ce n'est pas toujours mon prénom, c'est tout ce qui passe. Essayez cela a fonctionné pour moi.

Exécuter dans 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));

Ecrira dans la fenêtre «jack».


2
Ce n'est pas fiable. Il peut y avoir n'importe quel nombre de variables sur l'objet window avec la même valeur.
Taylor Buchanan

2

Vous pouvez réfléchir sur les types en javascript et obtenir le nom des propriétés et des méthodes, mais ce dont vous avez besoin, c'est qc comme Lambda Expressions Treesdans .NET, je pense que ce n'est pas possible en raison de la nature dynamique et du manque de système de type statique en javascript.


3
Je ne pense pas que JS soit en deçà des lambdas ou des outils associés de programmation fonctionnelle.

Mais je pense qu'il n'y a pas de structure équivalente aux arbres d'expression dans .NET.
Jahan

2

J'en avais besoin, je ne voulais pas utiliser d'objets et j'ai trouvé la solution suivante, renversant la question.

Au lieu de convertir le nom de la variable en une chaîne, je convertis une chaîne en une variable.

Cela ne fonctionne que si le nom de la variable est bien entendu connu.

Prends ça:

var height = 120;
testAlert(height);

Cela devrait afficher:

height: 120

Cela peut être fait comme ceci:

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

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

J'utilise donc la chaîne "height"et la transforme en variable heightà l'aide de la window[]commande.


2
Dans votre deuxième cas, la hauteur est une propriété de l' windowobjet car la variable du même nom a été déclarée à la portée de la fenêtre. Cela ne fonctionne que si la variable est déclarée à la portée de la fenêtre, pas dans une fonction / fermeture.
xoxox

2

Court moyen que j'ai trouvé jusqu'à présent pour obtenir le nom des variables sous forme de chaîne:

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

const whatsMyName = "Snoop Doggy Dogg";

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


1

Cela a fonctionné avec Internet Explorer (9, 10 et 11), Google Chrome 5:

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

Tableau de compatibilité du navigateur:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys


Google Chrome 5? vraiment??
avalanche1

2
@ avalanche1, selon le tableau de compatibilité des versions MDN.
danilo

0

J'ai créé cette fonction basée sur JSON comme quelqu'un l'a suggéré, fonctionne bien pour mes besoins de débogage

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")


-3

Non, il n'y en a pas.
De plus, si vous savez écrire variablesName(myFirstName), vous connaissez déjà le nom de la variable ("myFirstName").


11
Pas nécessairement vrai si le code est en cours de minification;)
Secret

9
Aussi le point d'utiliser par exemple nameof(myVariable)en C # (qui renvoie une chaîne "myVariable" est de se protéger contre les erreurs lors de la refactorisation ou de la modification du code. Un cas d'utilisation courant est d'ajouter le nom de la variable à un message d'erreur émis. Pour le la plupart des parties que je considère comme une chaîne de caractères une odeur de code, et je soupçonne que c'est pourquoi au moins Visual Studio les montre dans une couleur rouge / orange. Je sais que je sais, cette question concerne Javascript, mais je viens d'expliquer pourquoi j'ai terminé ici.
merrr

test var = 1235125142; console.log (Object.keys ({test}). pop ()) // "test"
bluejayke

1
@bluejayke Appelez-moi ignorant, mais après 8 ans, je ne vois toujours pas comment c'est mieux console.log('test')ou quand vous en auriez vraiment besoin.
deceze
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.