There is something very basic in JS I am not sure about. So I would like to ask.
The global object is window (or global of course for node.js). So we can for example get the variable's value by its name window[myVariableName].
The question is how can I do it with a local variable of a closure?
function myFunction()
{
// some code here
console.log(global_object[myVariableName]);
}
And may be even to get the variable's value by name, when the variable is global for the current closure but doesn't belong to window object.
From what I know about JS and how it works - it's impossible.
By the way, it's a very popular interview question how to get the variable's value by its name and it's never mentioned that the variable is global :).
eval('var value = ' + myVariableName + ';');
console.log(value);
Yeah, eval is evil but it is a solution (for a weird task though).
You can do it with the all evil eval
function test() {
var a = 5;
var myname = "a";
console.log(eval(myname))
}
test()
A variable can't be "global" to a closure.
It's either global or it's not.
If it's not, then it's within a function scope.
If it's within a function's scope, then the only way to get it, once you're outside of that function, is to have made it a property which you return from the function, or to append it to an object/array, which you passed into the function, or to create a function INSIDE of the function, which returns that variable...
// modifying an object
var my_func = function (obj) {
var hidden = 1;
obj.hidden = hidden;
};
var my_obj = {};
my_func(my_obj);
my_obj.hidden; // 1
// returning a function
var my_func = function () {
var a = 1,
b = 2,
c = 3,
get_a = function () { return a; },
get_b = function () { return b; },
get_c = function () { return c; };
return { a : get_a, b : get_b, c : get_c };
};
var my_obj = my_func();
my_obj.a(); // 1
my_obj.b(); // 2
my_obj.c(); // 3
If you would prefer to do this by "name", then you'd create one object in your closure, and you would create a function which took a string and looked for properties of that object, by name.
// get property by name
var my_func = function () {
var properties = {
a : 1,
b : 2,
c : 3
};
return {
get : function (name) {
return properties[name]; // returns undefined if it doesn't exist
}
};
};
var my_obj = my_func();
my_obj.get("a"); // 1
my_obj.get("b"); // 2
Now you can.
PS: eval(); isn't always guaranteed to work in the way that's described above.
For example, in the future, eval should run in its own scope and have no access to the calling function's scope (the same way building new Function("..."); works).
To take this one step further, to better answer your question about "global" as it pertains to scope:
window.bob = "Bob";
var outer_A = function () {
var mid_A = function () {
var inner_A = function () {
console.log("INNER-A");
console.log("bob = " + bob );
console.log("doug = " + doug);
};
inner_A();
};
mid_A();
},
outer_B = function () {
var mid_B = function () {
var doug = "Doug",
inner_B = function () {
console.log("INNER-B");
console.log("bob = " + bob );
console.log("doug = " + doug);
};
inner_B();
},
mid_C = function () {
var inner_C = function () {
console.log("INNER-C");
console.log("bob = " + bob );
console.log("doug = " + doug);
};
inner_C();
};
mid_B();
mid_C();
};
outer_A();
outer_B();
What does this get you?
You should end up with a printout that looks like:
/*
INNER-A
bob = Bob
doug = undefined
INNER-B
bob = Bob
doug = Doug
INNER-C
bob = Bob
doug = undefined
*/
Why would you end up with that?
Well, quite simply, because you have branching function-scopes.
doug is defined inside of mid_B.
Any functions which are created inside of mid_B can potentially access doug.
No functions created outside of mid_B can access doug.
When inner_C is asked to log doug, first it checks if doug exists in its own function.
If not, then it checks to see if it exists in its parent's function-scope (mid_C).
If not, then it checks to see if it exists in its parent's function-scope (outer_B).
If not, then it checks to see if it exists in its parent's function-scope (window).
If you make it all the way back to window, it has no parent function-scope...
...so if it's not even in window, then set the value to undefined.
Meanwhile, inner_B can't find doug, so it checks mid_B and finds doug.
This doesn't make doug "global".
It makes it in-scope.
"global" would be if outer_A, mid_A, inner_A, outer_B, mid_B, inner_B, mid_C and inner_C all had access...
...that would be bob.
bob is global.
It's global because it's attached to the window object (or defined as a var in the global-scope, which works pretty much the same way except when using delete).
And because all child functions have function-scopes which lead back to window, all functions can access anything defined as a property/var of window (unless there's a variable further up the scope-chain with the same name, at which point it picks the first one it hits).
This is what global means, and why doug is not a global variable in this example.