javascript中自由变量的查找只看函数定义位置,不看调用位置,由词法作用域决定;自由变量是未在函数内声明也非参数的变量,沿定义时的作用域链向上查找,与动态绑定的this有本质区别。

JavaScript中自由变量的查找,只看函数在哪定义,不看在哪调用。这是由词法作用域(静态作用域)机制决定的——引擎在函数创建时就固化了它的作用域链,后续执行时严格按这条链向上找。
自由变量的本质
自由变量是指在当前函数内部既没用 var/let/const 声明,也不是参数的变量。它必须从外部作用域“借”来。比如:
let x = 100;
function fn() {
console.log(x); // x 是 fn 的自由变量
}
这里 x 没在 fn 内声明,也不传参,所以是自由变量;它的值来自 fn 定义时所在的位置(即全局作用域),而不是将来调用时所处的环境。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
查找过程:沿着作用域链逐级向上
当函数访问一个自由变量时,JS 引擎会这样找:
- 先查当前函数自己的作用域(局部变量、参数)
- 没找到,就跳到该函数定义时的外层作用域(不是调用时的外层)
- 继续向上,直到全局作用域
- 全程不进入其他函数内部,也不看调用栈
典型例子:定义位置决定一切
let x = 10;
function outer() {
let x = 20;
return function inner() {
console.log(x); // 输出 20,因为 inner 在 outer 内定义
};
}
let x = 30; // 全局又改了一次
const fn = outer();
fn(); // 调用时全局 x=30,但 inner 仍输出 20
虽然 fn() 是在全局环境下执行的,但 inner 的定义位置在 outer 函数体内,所以它的外层作用域是 outer,取到的是 outer 中的 x = 20。
和 this 的关键区别
自由变量和 this 的绑定逻辑完全不同:
- 自由变量 → 看“函数写在哪”,编译期确定,静态绑定
- this → 看“函数怎么被调”,运行时确定,动态绑定
- 箭头函数的 this 是例外,它继承自定义时的外层 this,这点和自由变量类似,都是静态的
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










