javascript词法作用域在函数定义时就确定了变量查找路径,严格按代码嵌套结构向上回溯至全局;块级作用域(let/const)同样静态绑定;eval和with是破坏该机制的例外。

词法作用域在定义时就锁定了查找路线
函数的作用域链在它被创建(即定义)的那一刻就固定了,跟后续怎么调用无关。引擎会根据代码的嵌套结构,一层层向上回溯外层作用域,直到全局。
- 比如 inner 函数写在 outer 函数内部,那它的[[Environment]]就天然指向 outer 的词法环境
- 即使把 inner 提出来单独调用(如 return inner 后再执行),它依然沿原定义路径找变量
- 这种“静态绑定”让变量访问可预测,也支撑了闭包的实现
变量查找严格遵循作用域链顺序
当函数内引用一个变量时,JavaScript 引擎按以下顺序查找:
- 先查当前函数自己的作用域(含参数、let/const/var 声明)
- 没找到,就查定义时的外层函数作用域(注意:不是调用时的外层)
- 继续向上,直到全局作用域;全程找不到就抛 ReferenceError
例如:function foo() { let x = 1; return function bar() { console.log(x); } } const b = foo(); b(); —— bar 能输出 1,是因为它定义在 foo 内,作用域链包含 foo 的环境记录。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
块级作用域也属于词法作用域的一部分
ES6 的 let 和 const 声明引入了块级作用域,但它仍是词法的:作用域边界由 { } 在源码中的位置决定,而非运行时流程。
- if 或 for 块内用 let 声明的变量,只在该块内可见
- 函数内部的块不影响函数作用域本身,但会影响变量是否能被该块内代码访问
- 这种层级嵌套关系,在代码解析阶段(词法分析)就已建模完成
要小心那些“破坏”词法作用域的特例
绝大多数情况下,词法作用域稳定可靠,但有两个例外会动态干预变量查找:
- eval():在当前作用域中执行字符串代码,可能临时声明或覆盖变量
- with:将传入对象属性临时注入作用域链顶端,改变查找优先级(已不推荐使用)
它们会让变量查找不再完全静态,带来调试困难和性能损耗,现代代码应避免。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










