一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

JavaScript中词法作用域LexicalScope的时机确定

时间:2026-06-27 09:51:52 编辑:袖梨 来源:一聚教程网

JavaScript词法作用域在函数定义时确定,而非调用时;引擎在编译阶段依据函数物理位置静态构建作用域链,与调用位置无关,闭包和块级作用域均遵循此规则。

JavaScript 中词法作用域的确定时机,是在函数**定义时**,而不是调用时。

词法作用域在代码编写阶段就已固化

JavaScript 引擎在解析源代码(词法分析和编译阶段)时,就根据函数声明在代码中的物理位置,静态地建立其作用域链。这个过程与后续如何调用该函数完全无关。

  • 哪怕把一个内部函数赋值给变量、传到别的地方执行,它依然沿用定义时所在的位置所决定的作用域链
  • 例如:函数 innerouter 内部声明,那它的外层作用域永远是 outer 的作用域,哪怕之后在全局中调用 inner()
  • 这种“写在哪,就属于哪”的规则,就是“词法”二字的核心含义

与动态作用域的关键区别就在这里

动态作用域语言(如某些 Shell 脚本)会在运行时根据调用栈来决定变量查找路径。而 JavaScript 不会——foo() 函数访问变量 x,只看 foo 是在哪写的,不看谁调用了 foo

  • 典型例子:var value = 1; function foo() { console.log(value); } function bar() { var value = 2; foo(); } bar(); 输出 1,不是 2
  • 因为 foo 定义在全局,所以它向上找作用域链,直接找到全局的 value = 1
  • 即使 foo 是被 bar 调用的,也不会去查 bar 的作用域

作用域链的构建发生在函数创建时刻

每当函数对象被创建(比如函数声明、函数表达式求值),JS 引擎就会为其绑定一条作用域链。这条链由函数定义时能访问到的所有嵌套作用域组成。

立即学习“Java免费学习笔记(深入)”;

  • 全局函数 → 链上只有全局作用域
  • 函数 A 内定义函数 B → B 的作用域链包含 B 自身作用域 + A 的作用域 + 全局作用域
  • 闭包之所以能持续访问外部变量,正是因为这条链在函数创建时就已确定并被保留下来

ES6 块级作用域也遵循同一原则

letconst 声明的块级作用域,同样是依据代码书写结构静态确定的。

  • { let x = 1; function f() { console.log(x); } } 中的 f,定义在块内,因此可访问该块中的 x
  • 如果把 f 提到块外定义,哪怕逻辑上“紧挨着”,也无法访问块内的 x
  • 关键还是“定义位置”,不是“靠近程度”或“执行顺序”

热门栏目