JavaScript 闭包对比当地的
-
21-12-2019 - |
题
我有一个 Javascript 主文件,它包含在一个立即调用的闭包中(以免污染“全局”:
(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 作用域链有什么不理解的地方?
解决方案
你所期待的被称为 动态范围界定. 。这是一种有效的语言设计选择,尽管如今被广泛认为较差。这不是 Javascript 所做的。与许多流行语言一样,Javascript 使用 词汇范围. 。这意味着 confused
的范围不被视为子范围 fred
的,因为它的定义不在定义之内 fred
. 。事实是 fred
来电 confused
没有影响。
其他提示
var i,
closureVariable = [1,2,3,4];
创建两个新变量,可在 fred
函数以及在此范围内定义的函数。
这些变量与外部定义的任何变量完全不同 fred
范围,即使它们碰巧具有相同的名称。
这里的阴影意味着你的变量名为 "closureVariable"
防止对外部作用域中具有相同名称的变量进行任何直接访问。
当您通过省略分号重新定义闭彩变量时,它仅在FRED功能的上下文中重新定义。困惑的函数存在于关闭的上下文中,因此它仍然看到原始的闭彩变化。如果您在Fred函数内定义了困惑的函数,它将看到新的闭合变性,并打印[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]
})();
. 不隶属于 StackOverflow