You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

块级作用域无execution context时如何访问外层作用域变量?

块级作用域变量访问机制说明

先看你给出的示例代码:

function first(){
  let i=10;
  function second(){
    let j=20;
    console.log(i);
    if(j==20){
      console.log(i);
    } 
  }
  second();
}

你的疑问核心是混淆了执行上下文和词法作用域的作用边界,核心逻辑可以拆解为3点:

  • 只有全局代码执行、函数调用、eval执行三类场景会创建新的执行上下文,if/for这类块级代码确实不会生成独立的执行上下文,也没有独立的执行上下文级别的作用域链。
  • 词法作用域的规则是在代码预编译阶段就静态确定的,和运行时的调用逻辑无关。你示例里的if块属于second函数词法作用域内部的子块,本身就处于second的作用域覆盖范围内。
  • 块级代码运行时,用的就是所属外层函数的执行上下文的作用域链。

具体到你的代码运行过程:

  1. 调用first()时创建first的执行上下文,作用域链为[first变量对象, 全局变量对象],变量i存储在first的变量对象中。
  2. 执行到second()调用时创建second的执行上下文,作用域链为[second变量对象, first变量对象, 全局变量对象],变量j存储在second的变量对象中。
  3. 第一个console.log(i)执行时,沿second的作用域链查找,在first的变量对象中找到i=10完成输出。
  4. 进入if块时不会创建新的执行上下文,当前执行上下文仍然是second的,所以第二个console.log(i)还是沿second的作用域链查找i,和第一个的查找逻辑完全一致,自然能拿到对应的值。

补充说明:如果块内用let/const声明了同名变量,这些变量会存储在当前执行上下文变量对象的块级变量存储区,查找时会优先匹配块级变量,再匹配函数级变量,最后沿作用域链向上查找,整个过程都不需要新增执行上下文。

内容的提问来源于stack exchange,提问作者Manishpant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 10:27:05