40

Is there a way to find JavaScript variable on the page (get it as an object) by its name? Variable name is available as a string constant.

user59713
  • 435
  • 1
  • 5
  • 5
  • 1
    See also later question with additional answers: http://stackoverflow.com/questions/5117127/javascript-dynamic-variable-name and http://stackoverflow.com/questions/1664282/javascript-refer-to-a-variable-using-a-string-containing-its-name – goodeye May 23 '13 at 15:56

7 Answers7

36
<script>
var a ="test";
alert(a);
alert(window["a"]);
alert(eval("a"));
</script>
Catalin DICU
  • 4,610
  • 5
  • 34
  • 47
30

All JS objects (which variables are) are available within their scope as named properties of their parent object. Where no explicit parent exists, it is implicitly the window object.

i.e.:

var x = 'abc';
alert(window['x']); //displays 'abc'

and for a complex object:

var x = {y:'abc'};
alert(x['y']); //displays 'abc'

and this can be chained:

var x = {y:'abc'};
alert(window['x']['y']); //displays 'abc'
annakata
  • 74,572
  • 17
  • 113
  • 180
  • 6
    that's only true for globally scoped variables - if the scope is function-level, there's no object which allows access to the lexical environment – Christoph Apr 07 '09 at 12:15
  • Sure, but nothing helps you there. This assumes you can express the var as a dot notation construct. – annakata Apr 07 '09 at 12:46
  • If you need to do it within a function, the only solution is to put your vars in an objection, and access the object's keys, like this example: http://stackoverflow.com/questions/4109297/javascript-function-name-as-a-string-in-self-executing-function/4109730#4109730 – Ruan Mendes Feb 12 '11 at 01:27
  • @Juan - that wouldn't be function level scope though. – annakata Feb 14 '11 at 07:38
  • 4
    that's the point of my comment. You can't do it to local functions without eval. – Ruan Mendes Feb 18 '11 at 17:14
6

If you are wanting a variable that is declared in the global context, it is attached to the window object. ex: window["variableName"]. All variables are a hash table value within their scope.

If you have to use dotted notation, then you will want to follow kennebec's suggestion, to navigate through the object hierarchy. eval() can work as well, but is a more expensive operation than is probably needed.

Tracker1
  • 19,103
  • 12
  • 80
  • 106
5

If it's a global variable, you can look it up by name on the global object, since global variables are properties of the global object. On browsers, there's a global variable that refers to the global object called window, so:

var name = "foo";
window.foo = 42;
alert(Number(window[name])); // 42

But global variables are a Bad Thing(tm).

To do this without globals, use your own object:

var name = "foo";
var obj = {};
obj.foo = 42;
alert(Number(obj[name])); // 42

Both of the above work because in JavaScript, you can refer to an object property either with dot notation and a literal (obj.foo), or with bracketed notation and a string (obj["foo"]), and in the latter case, the string can be the result of any expression, including a variable lookup.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • What about if `obj` would be the variable to be accessed (and not `obj.foo`) - would `eval` be the only option then? – mxro Aug 30 '14 at 07:47
  • @mxro: If `obj` were a global, you could use `window["obj"]`. If it weren't, then you'd have to use `eval`. But I wouldn't, I'd change my code to put `obj` in a container so I could just look it up in the normal way. – T.J. Crowder Aug 30 '14 at 07:52
  • Yes, that sounds good. I think I initially created a variable in an `eval` statement, which then I could retrieve only through a second `eval` - but then changed the code that a container variable is created before the first `eval`; eliminating the need for the second `eval`. – mxro Aug 31 '14 at 01:40
  • @mxro: If you create a variable in an `eval`, you should be able to access it normally: `eval("var x = 42;"); console.log(x);` shows 42 in the console. (But there's almost never any reason to use `eval`.) – T.J. Crowder Aug 31 '14 at 06:47
  • Wow, thanks, that's also useful. But you are right, not very clean, I agree! – mxro Sep 01 '14 at 04:24
4

If your string references a 'deep' property of a global, like 'Yankee.console.format' you can step through the references:

String.prototype.deref= function(){
    // remove leading and trailing quotes and spaces
    var obj= this.replace(/(^[' "]+|[" ']+$)/g,'');

    var M= obj.match(/(^[\w\$]+(\.[\w\$]+)*)/);
    if(M){
        M= M[1].split('.');
        obj= window[M.shift()];
        while(obj && M.length) obj= obj[M.shift()];
    }   
    return obj || this;
}
kennebec
  • 102,654
  • 32
  • 106
  • 127
2
var getVar = function (obj) {
    for(var key in this) {
        if(obj === this[key]) return key;
    }
};

foo = 'foo';

console.log( getVar(foo) ); // => 'foo'

https://stackoverflow.com/a/17432007/1250044

Community
  • 1
  • 1
yckart
  • 32,460
  • 9
  • 122
  • 129
2

You could use eval()

James L
  • 16,456
  • 10
  • 53
  • 70
  • 3
    never *ever* use eval where you don't have to – annakata Apr 07 '09 at 10:03
  • 3
    vote up. simple question deserves a simple answer. i'd go with eval() if I for whatever reason needed to look at the contents of a variable by its name. – Peter Perháč Apr 07 '09 at 10:14
  • 3
    A). what's not simple about window[foo]? B). speed and security don't concern you then? eval is toxic, seriously – annakata Apr 07 '09 at 10:17
  • @annakata - i see your point, and never meant to say this solution is better than yours. i'm just saying that eval -does- resolve the question asked. – Peter Perháč Apr 07 '09 at 15:20
  • 1
    I'd hate for anyone to think this was a competition - I really honestly don't downvote for that - and I accept that eval does technically solve the problem, but nonetheless eval is the nuclear option. It's better if you don't have to use it. – annakata Apr 07 '09 at 15:39
  • 1
    @Peter, it's not a competition, but most well versed JS developers avoid `eval` and `with` like the plague. It should be OK to express dislike towards your solution. I would never post eval as a solution, unless there was no other, or it was just too cumbersome – Ruan Mendes Feb 12 '11 at 01:30
  • Indeed, the use of `eval` may give rise to a lot of security issues, but I think this is currently the only general solution -- if the function is not completely designed by yourself. Although I don't know the specific situations in which `eval` must be used, I think that as long as there is safety-related awareness before use, there is no need to exclude it. – LianSheng Sep 03 '21 at 00:35
  • Nobody has given a replacement for eval(name). All that repeated talk about window[name] is useless if you need to find the closest variable in scope, regardless whether it's a property of the global object, or in local scope, or in some closure below. How else to do that? – Gunther Schadow Jun 26 '22 at 08:40