对于闭包,变量不能是“全局的”。
它要么是全球性的,要么不是。
如果不是,那么它在函数范围内。
如果它在函数的范围内,那么在该函数之外获取它的唯一方法是将其设置为从函数返回的属性,或者将其附加到对象/数组中传递给函数,或者在函数内部创建一个函数,返回该变量...
// 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
如果您希望通过“名称”来执行此操作,那么您将在闭包中创建一个对象,然后创建一个函数,该函数接受一个字符串并按名称查找该对象的属性。
// 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
应该在自己的范围内运行,并且无法访问调用函数的范围(与构建new 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
*/
你为什么会这样呢?
好吧,很简单,因为你有分支功能范围。
doug
在 内定义mid_B
。
在其中创建的任何函数都mid_B
可以潜在地访问doug
.
在外部创建的任何函数都mid_B
不能访问doug
。
当inner_C
被要求记录doug
时,首先它检查是否doug
存在于它自己的函数中。
如果不存在,则检查它是否存在于其父函数范围(mid_C
)中。
如果不存在,则检查它是否存在于其父函数范围(outer_B
)中。
如果不存在,则检查它是否存在于其父函数范围(window
)中。
如果你一直回到window
,它没有父函数范围
......所以如果它甚至不在window
,那么将值设置为undefined
。
同时,inner_B
找不到doug
,所以它检查mid_B
并找到doug
。
这不会使doug
“全球”。
它成功了in-scope
。
“全球”将是如果outer_A
, mid_A
, inner_A
, outer_B
, mid_B
, inner_B
,mid_C
并且inner_C
所有人都可以访问...
...那将是bob
。
bob
是全球性的。
它是全局的,因为它附加到 window 对象(或在 中定义为 a var
,global-scope
除了使用 时,它的工作方式几乎相同delete
)。
并且因为所有子函数都有返回到的函数作用域window
,所以所有函数都可以访问任何定义为属性/变量的东西window
(除非在作用域链的上游有一个同名的变量,此时它会选择第一个它命中)。
这就是global
意思,为什么在这个例子doug
中不是变量。global