如何理解javascript的执行上下文【教程】

发布时间 - 2026-01-30 00:00:00    点击率:
JavaScript执行上下文分全局、函数、eval三种,仅在全局执行、函数调用、eval执行时创建;每个上下文含VariableEnvironment、LexicalEnvironment和this绑定三部分。

JavaScript 的执行上下文不是抽象概念,而是真实存在的、可推导的运行时结构——它决定了变量和函数在哪儿能被访问、值是什么、this 指向谁。理解它,关键不是背定义,而是看代码执行时“引擎到底做了什么”。

执行上下文分哪几种?什么时候创建?

JS 引擎只在三种时刻新建执行上下文:

  • 全局代码开始执行时 → 创建 Global Execution Context
  • 调用一个函数时 → 创建新的 Function Execution Context
  • 执行 eval()(不推荐)时 → 创建 Eval Execution Context

注意:iffor{} 块级作用域不会创建执行上下文,它们只影响词法环境(Lexical Environment),但不触发上下文栈入栈。

每个执行上下文内部有哪三块核心数据?

每个上下文都包含三个关键部分,且按固定顺序初始化:

  • VariableEnvironment:存放 var 声明、函数声明(会被提升)、function 参数 —— 这是真正参与变量提升(hoisting)的部分
  • LexicalEnvironment:存放 letconstclass 声明(暂存性死区 TDZ 就发生在这里);在函数中,它通常初始时与 VariableEnvironment 相同,但后续可能分离(比如遇到 withcatch 绑定)
  • this 绑定:由调用方式决定,不是由声明位置决定 —— obj.fn()thisobj,而 fn() 独立调用时在非严格模式下是 window(或 globalThis),严格模式下是 undefined

为什么 setTimeout 里的函数总拿不到最新值?跟执行上下文有关吗?

有关,但不是因为“闭包捕获了旧上下文”,而是因为:每次循环迭代都会创建**新的词法环境**(LexicalEnvironment),而 setTimeout 回调在将来执行时,会通过作用域链向上查找——它找的是自己被定义时所在那次迭代的环境,而不是最后一次。

典型例子:

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 0); // 输出 3, 3, 3
}

原因:var 声明绑定在 VariableEnvironment 上,整个循环共用一个 i;而改成 let 就输出 0,1,2,因为 let 每次迭代都生成新绑定,对应新 LexicalEnvironment

调试时怎么看当前执行上下文?

浏览器 DevTools 不直接显示“执行上下文对象”,但你可以间接观察它的行为:

  • 断点停住后,在 “Scope” 面板里看到的 “Closure”、“Script”、“Global” 就是当前上下文的 LexicalEn

    vironment
  • 展开 “Local” 可见当前函数的参数和 let/const 变量;“Script” 显示当前脚本级的 var 和函数声明
  • 右键变量 → “Re-evaluate in console”,可验证该变量是否处于 TDZ(报 ReferenceError: Cannot access 'x' before initialization

真正的难点不在识别上下文存在,而在于意识到:函数体内的自由变量,查的是它**定义时**所处的词法环境链,不是**执行时**所处的调用栈——这个错位,是绝大多数闭包误解和 this 失控的根源。


# javascript  # java  # js  # 浏览器  # access  #   # win  # 作用域  # 为什么  # if  # for  # catch  # const  # 循环  # class  # var  # 闭包 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel怎么创建自己的包(Package)_Laravel扩展包开发入门到发布  使用spring连接及操作mongodb3.0实例  JavaScript数据类型有哪些_如何准确判断一个变量的类型  Laravel Asset编译怎么配置_Laravel Vite前端构建工具使用  Laravel如何处理文件下载请求?(Response示例)  深圳网站制作平台,深圳市做网站好的公司有哪些?  郑州企业网站制作公司,郑州招聘网站有哪些?  微信小程序 闭包写法详细介绍  中山网站制作网页,中山新生登记系统登记流程?  Laravel storage目录权限问题_Laravel文件写入权限设置  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  node.js报错:Cannot find module &#39;ejs&#39;的解决办法  网站优化排名时,需要考虑哪些问题呢?  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  Laravel Admin后台管理框架推荐_Laravel快速开发后台工具  Linux后台任务运行方法_nohup与&使用技巧【技巧】  javascript日期怎么处理_如何格式化输出  如何在 Python 中将列表项按字母顺序编号(a.、b.、c. …)  深圳网站制作的公司有哪些,dido官方网站?  Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)  Python高阶函数应用_函数作为参数说明【指导】  Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】  Swift中循环语句中的转移语句 break 和 continue  Laravel如何实现图片防盗链功能_Laravel中间件验证Referer来源请求【方案】  如何用搬瓦工VPS快速搭建个人网站?  如何用AI帮你把自己的生活经历写成一个有趣的故事?  如何快速生成ASP一键建站模板并优化安全性?  如何快速查询网址的建站时间与历史轨迹?  Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】  浅谈redis在项目中的应用  Laravel DB事务怎么使用_Laravel数据库事务回滚操作  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  Mybatis 中的insertOrUpdate操作  Laravel如何操作JSON类型的数据库字段?(Eloquent示例)  Python自然语言搜索引擎项目教程_倒排索引查询优化案例  如何快速生成凡客建站的专业级图册?  Laravel事件监听器怎么写_Laravel Event和Listener使用教程  北京企业网站设计制作公司,北京铁路集团官方网站?  JS经典正则表达式笔试题汇总  ,在苏州找工作,上哪个网站比较好?  Laravel如何使用查询构建器?(Query Builder高级用法)  如何快速搭建个人网站并优化SEO?  Laravel如何实现事件和监听器?(Event & Listener实战)  如何挑选优质建站一级代理提升网站排名?  Laravel怎么连接多个数据库_Laravel多数据库连接配置  Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程  iOS中将个别页面强制横屏其他页面竖屏  如何用PHP快速搭建CMS系统?