JavaScript静态作用域指函数能访问的变量由其定义位置决定,而非调用位置;定义时即确定词法环境链,运行时不改变,如全局定义的foo调用时仍查全局value,与this的动态性形成对比。

JavaScript 中的静态作用域,核心就一点:函数能访问哪些变量,取决于它写在代码里的位置,而不是它在哪里被调用。
函数定义时就锁定了查找路径
引擎在解析代码阶段(还没执行)就根据函数体所在的位置,确定了它的词法环境链。这个链条不会因为之后怎么调用而变动。
- 比如一个函数写在全局下,它内部找变量就只看全局和自身,哪怕被嵌套函数传到十层深的地方去调用,也还是按原路径查
- 再比如一个内层函数写在另一个函数内部,它天然拥有对外层函数变量的访问权——这是写进去那一刻就定死的,不是靠“调用时外层刚好在运行”才临时获得的
典型例子:调用位置不影响结果
看这段代码:
let value = 1;
function foo() {
console.log(value);
}
function bar() {
let value = 2;
foo(); // 在 bar 里调用 foo
}
bar(); // 输出 1,不是 2
foo 定义在全局,所以它查 value 一定去全局找。bar 里虽然也有 value,但 foo 根本不“知道”bar 的存在——它没写在 bar 里面,就不纳入它的作用域链。
立即学习“Java免费学习笔记(深入)”;
和 this 的动态性形成对比
作用域是静态的,但 this 是动态的。同一个函数,换种方式调用,this 就可能指向不同对象。而作用域链从定义那一刻起就固定了,哪怕 this 指向变了,变量查找路线也不会变。
- 函数内访问普通变量:走词法作用域链,静态不变
- 函数内访问 this.xxx:this 值随调用方式变化,但 this 所指对象的属性查找,仍遵循该对象自身的原型链,不是作用域链
闭包就是静态作用域的自然结果
当一个函数返回了内部函数,而这个内部函数又引用了外层函数的变量,这些变量不会被回收——因为静态作用域规定:只要内部函数还存在,它定义时所依赖的外层词法环境就必须保留。
这不是靠运行时“记住调用栈”,而是靠引擎在定义时就建立并固化的作用域链结构。


















