JS中有一些非常基本的东西我不确定。所以我想问一下。
全局对象是window
(当然对于node.js来说是global
)。因此,我们可以通过名称window[myVariableName]
来获取变量的值。
问题是如何使用闭包的局部变量来实现?
function myFunction()
{
// some code here
console.log(global_object[myVariableName]);
}
当变量对于当前闭包是全局的但不属于window
对象时,甚至可以按名称获取变量的值。
根据我对JS及其工作原理的了解 - 这是不可能的。
顺便说一句,这是一个非常受欢迎的访谈问题,如何通过名称来获取变量的值,并且从未提及变量是全局的:)。
答案 0 :(得分:4)
eval('var value = ' + myVariableName + ';');
console.log(value);
是的,eval是邪恶的但 是一种解决方案(尽管这是一项奇怪的任务)。
答案 1 :(得分:2)
你可以用邪恶的eval
function test() {
var a = 5;
var myname = "a";
console.log(eval(myname))
}
test()
答案 2 :(得分:0)
变量不能成为闭包的“全局” 它要么是全球性的,要么不是全球性的。
如果不是,则它在功能范围内。
如果它在一个函数的范围内,那么获取它的唯一方法是,一旦你在该函数之外,就是将它作为一个属性从函数返回,或者将它附加到一个对象/数组,您传入函数,或创建函数INSIDE函数,返回该变量...
// 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”执行此操作,那么您将在闭包中创建一个对象,并且您将创建一个函数,该函数接受一个字符串并按名称查找该对象的属性。
// 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
。
“global”将是outer_A
,mid_A
,inner_A
,outer_B
,mid_B
,inner_B
,mid_C
并且inner_C
都可以访问...
......那将是bob
bob
是全球性的。
它是全局的,因为它附加到窗口对象(或在var
中定义为global-scope
,除了使用delete
时,其工作方式几乎相同。
并且因为所有子函数都具有返回window
的函数作用域,所有函数都可以访问被定义为window
的属性/ var的任何内容(除非在作用域链上有一个相同的变量)名称,此时它会选择它命中的第一个。
这是global
的含义,以及为什么doug
在此示例中不是global
变量。