259

Is there a way to get a variable name as a string in Javascript? (like NSStringFromSelector in Cocoa)

I would like to do like this:

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

--> myFirstName:John

UPDATE

I'm trying to connect a browser and another program using JavaScript. I would like to send instance names from a browser to another program for callback method:

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

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

...

From another program:

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

In PHP: How to get a variable name as a string in PHP?

fish potato
  • 5,319
  • 6
  • 27
  • 32
  • 3
    @delnan Indeed, +1. I can't think of another way to put it than "if you can write `variablesName(myFirstName)`, you already know the variable name." I'm trying, but I can't... – deceze Jan 05 '11 at 08:51
  • 2
    Dupe? http://stackoverflow.com/questions/417645/how-to-convert-variable-name-to-string-in-javascript – Ben Jan 05 '11 at 08:52
  • 1
    maybe for that you could store in a variable and later convert it to json for example {"instanceA": instanceA} and send it to the server using ajax or get/post call and that you can process in php and get name of the instance... – Geomorillo Mar 26 '14 at 00:44
  • 2
    @deceze, sure, you know the name, but that doesn't mean you can/want to type it in manually. Maybe you want to dump a bunch of variables for debugging purposes and don't feel like manually typing `console.log("myvar = " + myvar);` over and over again, for each variable. – Synetech Oct 06 '19 at 15:13

20 Answers20

182

You can use the following solution to solve your problem:

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

// returns "myFirstName"
Grant Miller
  • 27,532
  • 16
  • 147
  • 165
Fellow Stranger
  • 32,129
  • 35
  • 168
  • 232
  • 3
    This answer is similar to [@SethWhite's] (https://stackoverflow.com/a/39669231/5876282) but much simplified. Thanks! @bluejayke I think this answer comes years later after the original accepted answer. But yes, currently this is the best - except maybe the "pop()" usage suggested [below](https://stackoverflow.com/a/54345153/5876282) – B Charles H Jun 03 '19 at 14:44
  • 9
    is it possible to make function that will accept variable and print it's name? I've tried wrap your code inside a function but id returned me name which was used as argument – Wakan Tanka Feb 27 '20 at 11:14
  • @WakanTanka If yo create a proper question, I'll answer it there. – Fellow Stranger Mar 01 '20 at 07:20
  • 1
    @WakanTanka no, that would not work. As you discovered, it will just print the name you give the function argument. I think it helps to see how such a function would compile to an older Javascript spec. You can see in this example (https://jsfiddle.net/bigpopakap/wq891ghr/2/) that the {variable} syntax is just short for {variable: variable}, so it is impossible to use the variable name from the calling function – bigpopakap Jun 08 '20 at 17:25
  • 2
    Beware: this will not work if you use auto-refactoring in VS Code to rename `myFirstName` variable to `myLastName`, for example. It will do this: `Object.keys({ myFirstName: myLastName })[0];` – Maxim Mazurok Aug 26 '21 at 05:14
167

Like Seth's answer, but uses Object.keys() instead:

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

const someVar = 42
const displayName = varToString({ someVar })
console.log(displayName)
adiga
  • 34,372
  • 9
  • 61
  • 83
Donuts
  • 1,719
  • 2
  • 11
  • 4
  • 5
    @titusfx you can swap out const for let or var and it works just the same. But if you're using a transpiler for the object destructuring in the first place, it probably supports const already. – SethWhite Dec 12 '17 at 15:19
  • This seems to depend on using ES6? – O'Rooney Aug 22 '18 at 05:35
  • 2
    @O'Rooney Yes, it is ES6 specific. – Donuts Oct 17 '18 at 18:33
  • Excelent idea. With that, we can create a funcion capable of settiing multiple outputs by value, reading from terminal arguments: `const getArgs = (varObj:any) => { const keys = Object.keys(varObj); process.argv.slice(2).forEach((arg, i) => varObj[keys[i]] = arg); return varObj; }` – Murilo Perrone Apr 01 '21 at 02:40
58

In ES6, you could write something like:

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

console.log(varName);

Not really the best looking thing, but it gets the job done.

This leverages ES6's object destructuring.

More info here: https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/

SethWhite
  • 1,891
  • 18
  • 24
  • 1
    Great answer!! This particular use of object destructing is new to me (line 2 `let nameObject = {myVar}` so useful! It doesn't seem to be documented anywhere. Got any links? – Laurence Lord Dec 19 '18 at 09:45
  • 2
    @LaurenceLord it's called property shorthand. Assigning an object property without a definition (something: 'asdf'), will cause JS to define the property with the name of the variable and its value {something} === {something:something}. https://ariya.io/2013/02/es6-and-object-literal-property-value-shorthand – SethWhite Dec 19 '18 at 15:18
  • 1
    @LaurenceLord sidenote: it's "destruct**uring**" not "destruct**ing**" :) , although this in particular is not an "object" destructuring it's just the "Object Literal Property Value Shorthand" Seth mentioned. Object destructuring is a very specific term in JS referring to auto destructuring of objects like `...` or `var {a,b} = {a: "cool", b: "hot"}` etc. – jave.web Jun 17 '21 at 04:09
  • 2
    MDN link to the "Shorthand property names" - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#new_notations_in_ecmascript_2015 – jave.web Jun 17 '21 at 04:11
  • 1
    You mean ! const getVarNameFromObject = (nameObject) => { return Object.keys(nameObject)[0]; }; – gxmad Nov 27 '21 at 11:19
55

Typically, you would use a hash table for a situation where you want to map a name to some value, and be able to retrieve both.

var obj = { myFirstName: 'John' };
obj.foo = 'Another name';
for(key in obj)
    console.log(key + ': ' + obj[key]);
Al.G.
  • 4,327
  • 6
  • 31
  • 56
karim79
  • 339,989
  • 67
  • 413
  • 406
  • 238
    Doesn't answer the question though. – htafoya Nov 07 '17 at 22:14
  • 1
    @htafoya: Indirectly, yes - all properties of `obj` are printed as `name: value` pairs. But the explaining text could be more clear. – Matt Apr 20 '18 at 09:23
  • 2
    @Mat I understand the code, but generally the OP question is used for something more complex as dynamic assignations where you can select the variable from a generated string. Or where simply creating a dictionary to print a value is overkill. – htafoya Apr 20 '18 at 13:59
  • 3
    @htafoya - yes, something simple like nameof(varname) in C#. – Matt Apr 20 '18 at 14:00
  • 5
    I think the only reason this "doesn't answer the question" is because it doesn't start with "You cannot get the name of the constant or a variable in JavaScript. The closest thing to what you want...", like this other answer: https://stackoverflow.com/a/37393679 – bigpopakap Jun 08 '20 at 17:15
44

Get a string from any valid Javascript (variable, class):

const nameOf = (f) => (f).toString().replace(/[ |\(\)=>]/g,'');

Examples:

nameOf(() => myVariable)             // myVariable
nameOf(() => myVariable.name)        // myVariable.name
nameOf(() => myVariable.name.length) // myVariable.name.length
nameOf(() => myVariable.name[10])    // myVariable.name[10]
nameOf(() => MySuperClass)           // MySuperClass
Yauheni Pakala
  • 868
  • 9
  • 16
  • This is the only answer out of the numerous answers here that worked for me as My 'object' was replicating a C# enum eg: `var myEnum = {A:1, B:5, C:27} – Reahreic Apr 06 '21 at 12:32
  • Could you update your answer and create a `function`. I do not know how to use your code. – Radek May 01 '21 at 17:24
  • @Radek `const nameOf = function (f) { return (f).toString().replace(/[ |\(\)=>]/g,''); };` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – Yauheni Pakala May 02 '21 at 20:45
  • 2
    This is genius! – Qwerty Jun 20 '21 at 13:24
  • I'd recommend using `const nameOf = (f) => (f).toString().replace(/(\(\) => )/g,'');`. Then it's easy to modify, such as if you want to change "this.var" to "var", you can just do `const nameOf = (f) => (f).toString().replace(/(\(\) => this\.)/g,'');` – Adil Sep 04 '21 at 21:29
  • Now that should be the accepted answer – sayandcode Jul 06 '22 at 10:13
24

Probably pop would be better than indexing with [0], for safety (variable might be null).

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

// returns "Variable myFirstName with value 'John'"
Juangui Jordán
  • 6,091
  • 2
  • 35
  • 31
  • 5
    If myFirstName is passed to a function (containing this code) as argument v, then variableName is reported as v instead of myFirstName. – David Spector Sep 02 '19 at 12:49
  • Of course, when you do `const x = 'John'` and `const y = x`, `y` will just store a copy of the value. If instead the value was an object, `y` would just point at the object's reference. There can be multiple variable assignments to a value but there is no such thing as an "original" assignment not anything of that kind is stored anywhere, so it's impossible to know. You could wrap it, like in [this answer](https://stackoverflow.com/a/61779045/1931117). – Pedro Moreira Sep 14 '22 at 09:13
  • Even if `myFirstName == null`, `Object.keys({myFirstName})[0]` would still return `'myFirstName'`, no? – sleighty Jan 18 '23 at 18:19
20
var x = 2;
for(o in window){ 
   if(window[o] === x){
      alert(o);
   }
}

However, I think you should do like "karim79"

Praveen
  • 55,303
  • 33
  • 133
  • 164
cloverink
  • 588
  • 8
  • 23
  • 12
    This will only work at window scope (breaks when inside a function). – jpillora Jul 11 '15 at 05:01
  • 2
    Agreed - but its the closest to answering the OP's question. Gj. – The Dembinski Oct 18 '16 at 22:39
  • also if you are testing a primitive, it will alert all the variables that have the same value, or if two variables have the same object assigned to them. For example if the first line was `x = 2; y = 2;` or `x = {a:1}; b = x;` it would alert each of them – aljgom Mar 05 '17 at 06:54
  • If you want this to work in a **function scope** you can try using the function name instead of window, like: `var foo = function f(){ f.x = 2; for(o in f){ if(f[o]===f.x) alert(o); } }` then calling `f()` will alert 'x' – aljgom Mar 14 '17 at 18:51
  • 1
    @aljgom - good point. Here's a [fiddle](https://jsfiddle.net/64ykoj73/) to try it out. – Matt Apr 20 '18 at 09:20
  • This fails for: function outer() { var a={b:"c"}; alert(foo(a)); } – David Spector Sep 02 '19 at 12:59
  • Fails for: var a={b:"c"}; alert(name(a.b)); function name(v) { for(o in window){ if(window[o] === v){ return o; } } } – David Spector Sep 02 '19 at 13:04
19

This works for basic expressions

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

Example

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
  • 97,872
  • 84
  • 296
  • 452
  • 2
    This actually works pretty well! the only problem is when you pass in something like this: nameof(() => options.subOptions.displaySize) which returns "subOptions" Instead, I used this regex: exp.toString().match(/(?=[^.]*$)(\w+)/g)[0] – Jim Brown Nov 29 '16 at 21:54
  • 1
    I get undefined from: var a={b:"c"}; alert(name(a)); function name(exp) { exp.toString().match(/(?=[^.]*$)(\w+)/g)[0]; } // name – David Spector Sep 02 '19 at 12:55
13
var somefancyvariable = "fancy";
Object.keys({somefancyvariable})[0];

This isn't able to be made into a function as it returns the name of the function's variable.

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

Edit: Thanks to @Madeo for pointing out how to make this into a function.

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

You will need call the function with a single element array containing the variable. debugVar({somefancyvariable});
Edit: Object.keys can be referenced as just keys in every browser I tested it in but according to the comments it doesn't work everywhere.

Cadiboo
  • 165
  • 1
  • 4
12

Shortest way I have found so far to get the variables name as a 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
  • 945
  • 7
  • 10
6

Since ECMAScript 5.1 you can use Object.keys to get the names of all properties from an object.

Here is an example:

// 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 Code
  • 51,456
  • 28
  • 233
  • 198
6

best way using Object.keys();

example : for getting multi variables names in global scope

// multi variables for testing
var x = 5 , b = true , m = 6 , v = "str";

// pass all variables you want in object
function getVarsNames(v = {}){
  // getting keys or names !
  let names = Object.keys(v);
  // return array contain all names of variables 
  return names;
}

// testing if that work or not 
let VarsNames = getVarsNames({x , b , m , v});

console.log(VarsNames); // output is array [x , b , m , v]
0x00001F
  • 156
  • 1
  • 4
  • 13
4

For those who would like to print variableName and variableValue for debugging purposes, here is a function:

const printNameValue = (v)=> {
  var varName = (v).toString().replace(/[ |\(\)=>]/g, '')
  var varValue = (v)()
  // neat : console.log(varName,varValue);
  // with some coloring  : 
  console.log("\033[1;96m[\033[1;33m " + varName + " :\033[0;0m " + varValue+"\033[1;96m ]\033[0;0m");
}

Example:

const myNiceVariable = 1234
call:
printNameValue(()=> myNiceVariable )
result: display with colors in the terminal

anesboz
  • 412
  • 4
  • 10
3

This worked using Internet Explorer (9, 10 and 11), Google Chrome 5:

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

Browser compatibility table:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

danilo
  • 7,680
  • 7
  • 43
  • 46
2

When having a function write a function that changes different global variables values it is not always myfirstname it is whatever happens to be passing through. Try this worked for me.

Run in 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));

Will write to the window 'jack'.

Matt Smith
  • 45
  • 1
2

I needed this, don't want to use objects, and came up with the following solution, turning the question around.

Instead of converting the variable name into a string, I convert a string into a variable.

This only works if the variable name is known of course.

Take this:

var height = 120;
testAlert(height);

This should display:

height: 120

This can be done like this:

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

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

So I use the string "height" and turn that into a variable height using the window[] command.

SPRBRN
  • 2,406
  • 4
  • 35
  • 48
  • 2
    In your second case, height is a property of the `window` object because the variable of the same name was declared at window scope. This works *only* if the variable is declared at window scope, not in a function/closure. – xoxox Dec 11 '16 at 09:17
2

You can reflect on types in javascript and get the name of properties and methods but what you need is sth like Lambda Expressions Trees in .NET, I think it's not be possible due to dynamic nature and lack of static type system in javascript.

Jahan Zinedine
  • 14,616
  • 5
  • 46
  • 70
0

I've created this function based on JSON as someone suggested, works fine for my debug needs

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
  • 150
  • 1
  • 9
-1

If you're looking for something quick and dirty, this might work:

var zox = 150;

cl("zox");

function cl(c) {
    console.log(c + ': ' + this[c]); // zox: 150    
}
Sergio
  • 40
  • 3
  • 1
    That's not obtaining the variable name from the variable itself. It needs to know the variable name in advance. – jjmerelo Mar 30 '22 at 08:37
-4

No, there is not.
Besides, if you can write variablesName(myFirstName), you already know the variable name ("myFirstName").

deceze
  • 510,633
  • 85
  • 743
  • 889
  • 13
    Not necessarily true if the code is being minified ;) – Secret Feb 10 '14 at 09:16
  • 10
    Also the point of using e.g. `nameof(myVariable)` in C# (which returns a string "myVariable" is to shield against mistakes when refactoring or making other changes to the code. A common use case is to add the variable's name to an error message being thrown. For the most parts I consider string literals a code smell, and suspect that is why at least Visual Studio, shows them in a red/orange color. I know I know, this question is about Javascript, but I just explained why I ended here. – merrr Jan 28 '16 at 13:15
  • var test = 1235125142; console.log(Object.keys({test}).pop()) // "test" – B''H Bi'ezras -- Boruch Hashem Mar 12 '19 at 02:59
  • 3
    @bluejayke Call me ignorant, but after 8 years I still fail to see how that's any better than `console.log('test')` or when you'd really need it. – deceze Mar 12 '19 at 08:48