JavaScript变量查找遵循词法作用域规则,沿静态构建的作用域链逐级向上查找,未找到则抛ReferenceError;作用域链在函数定义时确定,查找过程严格按嵌套层级进行,不跳过中间层,且全局未声明变量不返回undefined而是报错。

JavaScript 中变量查找遵循“词法作用域”规则,当当前作用域找不到某个变量时,引擎会沿着嵌套的作用域链逐级向上(向外)查找,直到全局作用域;若全程未找到,则抛出 ReferenceError。
作用域链的构建发生在函数定义时
不是执行时。每个函数在创建时,其内部就记录了外层词法环境(即父级作用域),形成一条静态、只读的作用域链。例如:
function outer() {
const x = 10;
function inner() {
console.log(x); // 查找 x:先查 inner 自身作用域 → 找不到 → 查 outer → 找到 10
}
inner();
}
这里 inner 的作用域链是:[inner 本地] → [outer 本地] → [全局]。
查找过程严格按作用域层级向上,不跨函数或跳过中间层
即使多个同名函数嵌套,也只沿自己直接定义时的外层链查找,不会“跳”到其他分支或同级函数中:
立即学习“Java免费学习笔记(深入)”;
- 每层只检查自己的变量对象(VO)或词法环境记录
- 找到第一个匹配的绑定即停止(不存在变量提升覆盖或重查找)
- 遇到
with或eval会动态修改作用域链,但现代代码应避免使用
全局未声明变量会报错,而非返回 undefined
这是常见误区。如果变量既不在当前作用域,也不在任何外层作用域中定义(包括全局),JS 引擎不会返回 undefined,而是立即抛出 ReferenceError:
function foo() {
console.log(missing); // ReferenceError: missing is not defined
}
注意:这和 typeof missing 返回 "undefined" 不同——后者是语言特例,绕过了常规查找流程。
可通过 console.dir(function) 或调试器查看作用域链
在 Chrome DevTools 中断点停住函数执行,展开右侧 “Scope” 面板,就能清晰看到当前作用域及其上级词法环境。这也是验证变量是否真的“可访问”的最直接方式。


















