我有一个Javascript主文件,它被一个立即调用的闭包所包围(以免污染'global':
(function () {
"use strict";
var closureVariable = [];
...
}());
当从函数头中删除变量时,我发出了一个简单的,带头的编码错误,这样我的代码就有了逗号而不是分号:
function fred () {
var i,
closureVariable = [1,2,3,4];
confused();
}
function confused () {
console.log(closureVariable); // Prints '[]'
}
当然'var i'行上缺少的分号就是问题所在。然而,我认为应该发生的行为是我现在本地定义的变量'closureVariable'应该遮蔽更高级别的范围定义,并且我的本地定义变量的值应该可用于范围链中较低的函数(也就是说,'confused'函数应该打印出'[1,2,3,4]';
我在这里不了解Javascript范围链?
答案 0 :(得分:3)
var i,
closureVariable = [1,2,3,4];
生成两个新变量,可在fred
函数和此范围中定义的函数中使用。
这些变量与fred
范围之外定义的任何变量完全不同,即使它们碰巧具有相同的名称。
此处的阴影意味着名为"closureVariable"
的变量会阻止对外部作用域中具有相同名称的变量的任何直接访问。
答案 1 :(得分:3)
您期望的是动态范围。这是一种有效的语言设计选择,尽管今天被广泛认为是劣等的。这不是Javascript的作用。与许多流行语言一样,Javascript使用词法范围。这意味着confused
的范围不被视为fred
的子范围,因为其定义不在fred
的定义范围内。 fred
调用confused
的事实无效。
答案 2 :(得分:1)
当您通过省略分号重新定义closureVariable时,它仅在fred函数的上下文中重新定义。混淆函数存在于闭包的上下文中,因此它仍然可以看到原始的closureVariable。如果你在fred函数中定义了你的混淆函数,它会看到新的closureVariable并打印[1,2,3,4]
(function () {
"use strict";
var closureVariable = [];
function fred () {
var i,
closureVariable = [1,2,3,4];
function confused () {
console.log(closureVariable);
}
confused(); // print [1,2,3,4]
}
})();
或者如果你想从fred()
之外打电话混淆(function () {
"use strict";
var closureVariable = [];
var confused;
function fred () {
var i,
closureVariable = [1,2,3,4];
confused = function () {
console.log(closureVariable);
}
}
confused(); // print [1,2,3,4]
})();