【发布时间】:2012-06-24 06:56:48
【问题描述】:
我正在尝试了解 JavaScript 范围规则。我在教科书和文档中读到的内容令人困惑。
在我看来,JavaScript 是一种静态(或词法)作用域语言 - 当尝试将变量名绑定到变量(定义)时,会使用代码的词法结构。
执行上下文似乎类似于调用堆栈上的堆栈帧。每个执行上下文都有一个变量对象,所有局部变量(关联函数的)都在该变量对象上定义。这些变量对象链接在一起以提供从堆栈顶部的变量对象到堆栈底部的变量对象(窗口对象)的“范围链”。在将变量名称绑定到变量时,从上到下搜索此范围链。这与 C/C++/Java 等静态范围语言非常相似。
似乎有一个与 C/C++/Java 相关的重要区别——可以访问在堆栈帧不再位于调用堆栈上的函数中定义的变量,如下例所示:
var color = "red";
var printColor;
function changeColor() {
var color = "green";
printColor = function(msg) {
alert(msg + color);
}
printColor("in changeColor context, color = "); // "green"
}
changeColor();
// stack frame for "changeColor" no longer on stack
// but we can access the value of the variable color defined in that function
printColor("in global context, color = "); // "green"
我做对了吗?还有其他我应该注意的问题吗?
提前致谢
【问题讨论】:
-
今天 HN 的一篇非常彻底的帖子涉及到这一点:What is the Execution Context & Stack in JavaScript?
-
这称为闭包。您分配给
printColor的函数可以访问changeColor中定义的所有变量,即使在函数终止后也是如此。我不知道这在 C 中是怎样的。 -
@FelixKling 差不多。但是 changeColor 也是在全局范围内定义的,因此它的范围永远不会被垃圾收集。
标签: javascript scope executioncontext