15

Possible Duplicate:
How can I access local scope dynamically in javascript?

Hi all.
We all know that you can access a property of a javascript object by it's name using the [] syntax.. e.g. ob['nameOfProperty'].

Can you do the same for a local variable? Another answer here suggested the answer is to use window['nameOfVar']. However, this only worked for the poster as he was defining variables at window-level scope.

I assume that this must be possible in general, as Firefox's Firebug (which I believe is written in javascript) can show local and closure variables. Is there some hidden language feature I'm not aware of?

Specifically, here's what I want to do:

 var i = 4;
 console.log(window['i']); // this works..

 function Func(){
     var j = 99;

     // try to output the value of j from its name as a string
     console.log(window['j']); // unsurprisingly, this doesn't work
 }

 Func();
Community
  • 1
  • 1
Ben Clayton
  • 80,996
  • 26
  • 120
  • 129
  • 1
    See http://stackoverflow.com/questions/598878/how-can-i-access-local-scope-dynamically-in-javascript – Roatin Marth Feb 25 '10 at 19:16
  • You can also have a look http://stackoverflow.com/questions/1119335/javascript-local-variable-declare http://stackoverflow.com/questions/598878/how-can-i-access-local-scope-dynamically-in-javascript – Rouan van Dalen Feb 25 '10 at 18:42

5 Answers5

15

I'm not aware of anything built into JavaScript to reference local variables like that (though there probably should be considering all variables are internally referenced by strings).

I'd suggest keeping all your variables in an object if you really need to access by string:

var variables = {
    "j": 1
};
alert(variables["j"]);

Update: It kind of bugs me that there's no way to do this like you want. Internally the variable is a mutable binding in the declarative environment records. Properties are bound to the object they're a property of through the object's environment records, but there's actually a way to access them using brackets. Unfortunately, there's no way to access the declarative environment records the same way.

Bob
  • 7,851
  • 5
  • 36
  • 48
8

Accessing the variable with window or any other global accessor won't work because the variable is not globally accessible. But you can use can use eval to evaluate any expression:

<script>
function test(){
   var j = 1; 
   alert(eval("j"));
}

test();
</script>
PanJanek
  • 6,593
  • 2
  • 34
  • 41
  • Thanks Pan. I guess I should have been clearer in the question and said without using eval. :-) Looks like this is the only way of doing what I want without modifying the pattern though. – Ben Clayton Feb 26 '10 at 10:30
2

No, because the variable is only accessible from within the execution contexts that contain the variable's scope.

Put another way, the only way you can access j is if you are accessing it from something in the scope of test -- via an inner function, or whatever. This is because j, in a sense, doesn't exist to objects with a wider scope, like the global object. If it were otherwise, then variable names would have to globally unique.

ntownsend
  • 7,462
  • 9
  • 38
  • 35
2

What about:

<script>
    function Func(){
        var fn = arguments.callee;
        fn.j = 99;
        console.log(fn['j']);
    }
    Func();
    console.log(window['j']); //not global
    console.log(Func['j']); //but not private
</script>
Mic
  • 24,812
  • 9
  • 57
  • 70
  • Since Func is not an object this points to the global object. You're essentially saying window['j'] – Bob Feb 25 '10 at 19:10
  • @Bob, Did you try it before downvoting me? Because it works. – Mic Feb 25 '10 at 19:21
  • @Bob, ok, I got you, you're right – Mic Feb 25 '10 at 19:25
  • @Mic: That case may work but only because you've assigned a property to `this` rather than declared a local variable with `var`, which is what the OP clearly stated he wanted. – Tim Down Feb 25 '10 at 19:26
  • @Bob, @Tim Update with another option – Mic Feb 25 '10 at 19:28
  • I didn't down vote you...I don't know who did. There, I upvoted :) – Bob Feb 25 '10 at 19:41
  • @Bob, Anyway I'm not sure this should be used, there are more classical ways of handling this. Your answer for instance, I politely replied a +1 then :) – Mic Feb 25 '10 at 19:58
2

No, this isn't possible in general. JavaScript resolves identifiers inside a function using the scope chain; there's no single object that contains all the variables in scope, and the objects in the scope chain are inaccessible from JavaScript running in the page.

Tim Down
  • 318,141
  • 75
  • 454
  • 536