我有一个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‘应该隐藏了更高级别的范围定义,并且我的本地定义变量的值应该可以用于范围链中较低的函数(也就是说,函数’困惑‘应该打印出'1,2,3,4';
我对Javascript作用域链有什么不理解的?
发布于 2014-02-25 14:59:02
您所期望的是所谓的动态作用域。这是一个有效的语言设计选择,尽管今天被普遍认为是低劣的。只是这不是Javascript做的。与许多流行语言一样,Javascript使用词法作用域。这意味着confused的作用域不被视为fred的子范围,因为它的定义不在fred的定义之内,fred调用confused这一事实没有影响。
发布于 2014-02-25 14:58:07
var i,
closureVariable = [1,2,3,4];使两个新变量在fred函数和在此范围内定义的函数中可用。
这些变量与在fred作用域之外定义的任何变量完全不同,即使它们恰好具有相同的名称。
在这里,隐藏意味着名为"closureVariable"的变量阻止对外部作用域中具有相同名称的变量的任何直接访问。
发布于 2014-02-25 15:00:31
当您通过省略分号来重新定义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()外部调用from ()
(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]
})();https://stackoverflow.com/questions/22017847
复制相似问题