全球closures的目标

JS中有一些非常基本的东西我不确定。 所以我想问一下。

全局对象是window (或者当然是global的node.js)。 所以我们可以通过它的名字window[myVariableName]得到variables的值。

问题是如何用闭包的局部variables来做到这一点?

 function myFunction() { // some code here console.log(global_object[myVariableName]); } 

当variables是当前闭包的全局variables但不属于window对象时,甚至可以通过名称获取variables的值。

从我对JS的了解以及它如何工作 – 这是不可能的。

顺便说一下,这是一个非常受欢迎的面试问题,如何通过名称获取variables的值,而且从来没有提到该variables是全局的。

 eval('var value = ' + myVariableName + ';'); console.log(value); 

是的,eval是邪恶的,但它一个解决scheme(虽然一个奇怪的任务)。

你可以用邪恶的eval来做到这一点

 function test() { var a = 5; var myname = "a"; console.log(eval(myname)) } test() 

variables不能是“全局”到闭包。
这可能是全球性的,或者不是。

如果不是,那么它在function范围内。

如果它在函数的作用域内,那么一旦你不在函数中,唯一的方法就是使它成为你从函数返回的属性,或者把它附加到一个对象/数组中,传递给函数,或者创build函数的INSIDE函数,它返回该variables…

 // 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 

如果你希望通过“name”来实现,那么你需要在闭包中创build一个对象,然后创build一个函数,该函数接受一个string并按名称查找该对象的属性。

 // 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 

现在你可以。

PS: eval(); 并不总是保证以上述方式工作。
例如,将来, eval应该在自己的范围内运行,并且无法访问调用函数的作用域(与构buildnew Function("...");作品的方式相同)。

编辑

更进一步,为了更好地回答关于"global"问题,因为它涉及范围:

 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(); 

这是什么让你?
你应该得到一个打印输出,如下所示:

 /* INNER-A bob = Bob doug = undefined INNER-B bob = Bob doug = Doug INNER-C bob = Bob doug = undefined */ 

你为什么最终呢?
呃,很简单,因为你有分支function范围。
doug被定义在mid_B里面。
mid_B中创build的任何函数都可能访问道doug
mid_B之外创build的任何functionmid_B不能访问道doug

inner_C被要求logging道doug ,首先检查道格是否存在于自己的函数中。
如果不是,则检查它是否存在于其父函数范围( mid_C )中。
如果不是,那么它检查它是否存在于其父函数范围( outer_B )中。
如果不是,则检查它是否存在于其父函数作用域( window )中。
如果你一直回到window ,它没有父function范围…
…所以如果它甚至不在window ,那么将该值设置为undefined

同时, inner_B找不到doug ,所以它检查mid_B并finddoug

这不会使道doug “全球”。
它使它in-scope

如果outer_Amid_Ainner_Aouter_Bmid_Binner_Bmid_Cinner_C都有访问权限, mid_C “全局”。

…会是bob
bob是全球性的。

它是全局的,因为它附着在窗口对象上(或者在global-scope定义为var ,除了使用delete之外,其工作方式几乎相同)。
因为所有的子函数都有函数范围,所有的函数都可以访问定义为window属性/ var的任何东西(除非在同一个名字的范围链上有一个variables,第一个命中)。

这就是global手段,为什么道doug在这个例子中不是一个globalvariables。