1

I am now in the process of removing most globals from my code by enclosing everything in a function, turning the globals into "pseudo globals," that are all accessible from anywhere inside that function block.

(function(){

var g = 1;

var func f1 = function () { alert (g); }

var func f2= function () { f1(); }

})();

(technically this is only for my "release version", where I append all my files together into a single file and surround them with the above....my dev version still has typically one global per js file)

This all works great except for one thing...there is one important place where I need to access some of these "globals" by string name. Previously, I could have done this:

 var name = "g";
 alert (window[name]);

and it did the same as

 alert(g);

Now -- from inside the block -- I would like to do the same, on my pseudo-globals. But I can't, since they are no longer members of any parent object ("window"), even though are in scope.

Any way to access them by string?

Thanks...

rob
  • 9,933
  • 7
  • 42
  • 73

3 Answers3

1

Basically no, as answered indirectly by this question: Javascript equivalent of Python's locals()?

Your only real option would be to use eval, which is usually not a good or even safe idea, as described in this question: Why is using the JavaScript eval function a bad idea?

If the string name of those variables really and truly is defined in a safe way (e.g. not through user-input or anything), then I would recommend just using eval. Just be sure to think really long and hard about this and whether there is not perhaps a better way to do this.

Community
  • 1
  • 1
Eli Courtwright
  • 186,300
  • 67
  • 213
  • 256
  • Ahh, yeah, eval. Not sure why I didn't think of that. But yeah, I don't think I want to go there. :) – rob May 04 '10 at 21:02
  • 1
    Is there any reason he can't just name the function he is using to wrap the code, and then access the "global" as a member of that object? That's what I suggest in my answer, I'm just curious if there's something I'm missing that you could explain. – MisterMister May 05 '10 at 02:32
  • @MisterMister: That may very well be a good approach, depending on the specifics of his code, how it's structured, and exactly why he needs to access a global by a string name, and how much refactoring would be required in order to make this approach work. Without those specifics I'm really not sure what would be best, though your answer is in general a sound approach. – Eli Courtwright May 05 '10 at 03:16
  • @ Eli Courtwright That's what I figured, I was just curious if there was something I was missing (which happens regularly :-p). Thanks. – MisterMister May 05 '10 at 07:06
  • 1
    @MisterMister....yeah, not really what I want. I can create an object and access that (whether it be the function name or whatever), but I want to be able to access variables that are created with a simple "var whatever". It is a special purpose need...for something that works differently in dev/debug mode than production mode....in one case they will be globals, in other cases they will be "protected". I can work around the lack of being able to do this the way I'd prefer, but figured I'd check first. – rob May 05 '10 at 22:30
1

You can name the function you are using to wrap the entire code.

Then set the "global" variable as a member of that function (remember functions are objects in JavaScript).

Then, you can access the variable exactly as you did before....just use the name of the function instead of "window".

It would look something like this:

var myApp = new (function myApp(){

   this.g = "world";

   //in the same scope
   alert ( "Hello " + this["g"]);

})();

//outside
alert ( "Hello " + myApp["g"]);
MisterMister
  • 396
  • 1
  • 6
0

if you want to access something in a global scope, you have to put something out there. in your case it's probably an object which references your closed off function.

var obj1 = new (function(){

var g = 1;

var func f1 = function () { alert (g); }

var func f2= function () { f1(); }

})();

you can add a method or property as a getter for g. if the value of g isn't constant you might do like

this.getG = function() { return g; };

you can work from there to access items by name, like

alert( obj1["getG"]() );
alert( window["obj1"]["getG"]() );
lincolnk
  • 11,218
  • 4
  • 40
  • 61