位置:首页 > JavaScript > JavaScript词法作用域如何理解由编写位置而非调用位置决定

JavaScript词法作用域如何理解由编写位置而非调用位置决定

时间:2026-08-12  |  作者:游戏探长  |  阅读:0

词法作用域的核心是:函数能访问哪些变量,取决于它在源代码中的定义位置,而不是调用位置。这个作用域链在函数声明时就已经确定,运行时不会因为调用方式变化而改变,这一点与动态的 this 形成鲜明对比。

Ja vaScript 中怎么理解词法作用域决定于编写位置而非调用位置

词法作用域可以简单理解为一句话:函数能拿到哪些变量,不看它在哪里被调用,只看它定义在哪里。

这种对应关系在代码解析时就已经确定。到了运行阶段,也不会因为调用位置变化而改变。

定义时就确定变量查找路径

当 Ja vaScript 引擎读到函数声明时,比如 function foo() { ... },会立刻根据它所处的嵌套层级,建立对应的词法环境链。

这条链会从当前函数开始,逐层连接到外层函数,最后到全局环境。

  • 写在全局下的函数,它的作用域链只包含全局环境
  • 写在一个函数内部的函数,它的作用域链天然包含该外层函数的词法环境
  • 这个链条不是运行时根据“谁在调用我”临时拼出来的,而是定义时就固化下来的结构

调用位置不会影响变量查找

即使把一个函数传到很深的回调中,放进定时器,或者绑定到事件里,它内部查找变量时,依然走定义时就确定好的那条路径。

  • let value = 1;
  • function foo() { console.log(value); }
  • function bar() { let value = 2; foo(); }
  • bar(); // 输出 1,不是 2

这里的关键是:foo 是在全局定义的,所以它只能沿着自己的词法环境链向上查找。

因此,它根本“看不见”bar 里的 value,因为这个变量不在它的词法环境链上。

与 this 的动态性形成对比

this 的值会随着调用方式变化。比如直接调用、方法调用、call/apply,以及箭头函数继承,都可能让 this 指向不同对象。

但变量查找并不是这样,它不取决于调用方式。

  • 普通变量(如 valuecount)严格按词法作用域链查找,静态不变
  • this.xxx 中的 this 是动态的,但一旦 this 确定了,查属性仍走该对象的原型链,不是作用域链

闭包是词法作用域的自然结果

当一个函数返回内部函数,并且内部函数引用了外层变量时,这些变量之所以还能继续存在,本质上就是因为引擎保留了它定义时依赖的词法环境。

  • 不是靠记住“调用时外层还在执行”,而是靠定义时就建立并冻结的作用域链
  • 哪怕外层函数早已执行完毕、执行上下文被销毁,只要闭包还存在,那些变量就继续保留在内存中

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多