当前位置: 首页 > news >正文

面试官问你这些,其实是在问你JavaScript执行原理!

一、执行上下文(Execution Context)与环境记录(Environment Record)

执行上下文是函数/全局/模块代码执行时的抽象环境,包含几部分:

  • LexicalEnvironment​(词法环境)——存 let/const/class、catch 参数、块级作用域、函数参数、箭头函数 this 等词法绑定
    • 不挂载到 global object
    • 有 ​TDZ​(Temporal Dead Zone)
  • VariableEnvironment​(变量环境)——用于 var 与 function 函数声明的绑定。
    • 变量提升到 undefined
    • 可写可删性有限(var 声明的全局属性不可被 delete)
  • ThisBinding​(this 绑定)等。

旧书里常讲 VO 是全局的变量对象,AO 是函数的变量对象,而 VO 会绑定到 GO(window/global)上。这些等等都是 ES5/更早表述,我们这里就不再谈论了。

ER(环境记录)是用来真正“存变量、查变量”的地方。

Execution Context:LexicalEnvironment: {EnvironmentRecord (DeclarativeEnvironmentRecord)outer: parent LexicalEnvironment}VariableEnvironment: {EnvironmentRecord (DeclarativeEnvironmentRecord)outer: parent LexicalEnvironment}ThisBinding: <value>

当进入一个执行上下文(比如函数调用或全局脚本)时,通常有两步:

  1. 解析/创建阶段(Creation)​:处理声明
    1. 所有函数声明会被绑定(并指向函数对象);
    2. var 声明会在变量环境中创建并初始化为 undefined (这就是“提升”表现);
    3. let/const 则会在词法环境中记录但处于 TDZ(Temporal Dead Zone)直到初始化。
  2. 执行阶段(Execution)​:执行代码,赋值、运行语句、创建闭包等。

1 Environment Record 的三种实现形式

环境记录是 JS 变量体系的“底层数据结构”。

1.1 DeclarativeEnvironmentRecord(DER)

​绑定绝大多数作用域,不会挂载到全局,也不会被 delete,​用来存:

  • let
  • const
  • class
  • 函数的形参(包括默认值表达式)
  • 内部函数声明(非全局的 function)
  • catch(e)e
  • 箭头函数没有 ThisBinding(this),但内部引用的变量也是 DER 查找

每个 DER 长这样:

DeclarativeEnvironmentRecord:bindings: {变量名: {value: <值>,mutable: true/false,initialized: true/false, // 用于 TDZdeletable: true/false,strict: true/false}}

TDZ 其实是更满足我们直观的编程特性,很多其他语言天然支持,so JavaScript 又在弥补自己的设计缺陷?

console.log(a); // ReferenceError
let a = 1;

1.2 ObjectEnvironmentRecord(OER)

绑定到一个实际对象,用于 “使用对象作为作用域” 的场景。

注意:这里的使用对象作为作用域块级作用域写法都是 {} ,一个是作用域块,一个是对象,但却是两个不同的东西。

1.2.1 全局作用域中的 var/function 声明

全局执行上下文的 VE 用 OER 来容纳 ​var 和 function 声明​,其底层对象就是全局对象,OER 直接操作 globalObject 的属性:

var a = 1;
console.log(window.a); // 1

1.2.2 with 语句作用域

with(obj) 会创建一个 OER,将 obj 当成作用域链的一部分,使得“找变量时”会先查这个对象属性。

const o = { x: 1 };with(o) {console.log(x); // 来自 o.x
}

with 语句极少使用。

ObjectEnvironmentRecord:object: <绑定的对象>bindings: 就是 object 的属性

OER 内没有“自有存储”,所有变量查找实际上是 ​属性查找​。

1.3 FunctionEnvironmentRecord(FER)

​专用于函数执行上下文,​它是函数专属的一种 ER,包含函数独有的数据:

  • 函数的内部绑定(var/function 声明)
  • 参数(包括默认值、rest 参数)
  • thisBinding
  • superBinding
  • homeObject(用于 super)
  • new.target
FunctionEnvironmentRecord:thisBinding: <值>thisBindingStatus: lexical / initialized / uninitializedfunctionObject: fn 本身homeObject: 用于 super 的对象newTarget: new.target 的值bindings:var/function 声明参数名称 → 绑定

函数内 let/const 会进入另一个 DeclarativeEnvironmentRecord(LE),而不是进入 FER。

一个函数执行时:

Execution Context├─ LexicalEnvironment│     ├─ DeclarativeEnvironmentRecord(let/const)│     └─ outer → 上层作用域├─ VariableEnvironment│     └─ FunctionEnvironmentRecord(var/参数)└─ ThisBinding 由调用决定

全局执行时:

LexicalEnvironment:DER(let/const)
VariableEnvironment:OER(var/function → global object)
ThisBinding: global object(非严格)

二、变量提升(Hoisting)与 TDZ(Temporal Dead Zone)

  • function 声明:整体提升(函数体也提升)—— 在创建阶段函数对象已绑定,可以直接调用(在同一执行上下文)。
  • var:变量名提升到变量环境,初始值 undefined
  • let/const:不会被初始化为 undefined,在创建阶段记录但进入 ​TDZ​,在实际执行到声明处才完成初始化。访问 TDZ 会抛 ReferenceError
  • class:类似于 let(处于 TDZ,类声明不会提升到可用状态)。

三、作用域链与闭包(Scope Chain & Closure)

  • 作用域链:每个执行上下文的词法环境都有一个 outer 指针,形成链式结构。查找变量时,从当前环境往外查直到全局。
  • 闭包:当一个内部函数引用了外部函数的变量,外部函数的词法环境就不会被 GC(只要闭包可达),从而形成闭包。闭包保存的是对​环境记录​(变量的引用),不是对变量值的“拷贝”。
function makeCounter() {let count = 0;return function () {return ++count;};
}
const c = makeCounter();
c(); // 1

三、报错时的执行上下文与 Stack Trace(“报错执行上下文”)

  • 抛出错误(throw)会立刻打断当前执行上下文的正常流,开始查找最近的 try...catch
    • 若找到匹配的 catch,控制权跳转到 catch 块(catch 会创建新的词法环境记录 exception 绑定);
    • 若没有,错误会沿调用栈向上抛,最终变为未捕获异常(浏览器在控制台显示 stack trace,Node 会导致进程退出或触发 unhandledRejection/uncaughtException)。
  • Promise 内抛错误:若未处理会进入 Promise 的 rejected 状态;若没有 .catch() 或全局 unhandledrejection 处理器,会报未处理拒绝。
http://www.fuzeviewer.com/news/51560/

相关文章:

  • 苏州建设职业培训中心网站wordpress付费剧集网站
  • 免费网站设计素材湖州注册公司
  • 江门17年seo优化技术软件重庆搜索引擎优化
  • 做淘宝客网站能有效果吗广东个人 网站备案
  • 做游戏直播什么游戏视频网站网站改版影响seo吗
  • 专业的微网站哪家好易代理ip官网
  • 信专业广州网站建设青海项目信息网官网
  • 自己做的网站发布到网上视频播放不了企业优化推广
  • 推荐网站在线看兄弟们视频网站开发问题
  • 烟台专业做网站专业网页制作多少钱
  • 如何快速更新网站快照wordpress主题安全
  • seo优化网站优化排名徐州建设工程交易网柖标公告
  • 11/18
  • 重庆做网站微信的公司响水网站建设服务商
  • 太原网站建设 网站制作中山网页建站模板
  • 电影网站空间配置网店推广的作用是什么
  • 网站开发工程师的职位什么是网络营销信息
  • 网站更换域名 换程序 SEO章丘灵通环保设备在哪个网站上做的
  • 公司做网站的流程作图的步骤河北邢台做wap网站
  • 做wordpress 下载站潍坊专业做网站
  • 深圳网站建设哪家公司好做问卷调查用哪个网站
  • 详细介绍:技术人互助:城市级充电系统(Java 微服务)的落地细节,含 demo 和设备适配经验
  • 做网站好还是网店网站内页权重
  • 张家港外贸型网站建设安全的响应式网站建设
  • 网站开发 软件开发wordpress如何让别人注册
  • 牡丹江建设行业协会网站php个人网站源码带音乐
  • 深圳专业企业网站制作免费手游平台app
  • 山东川畅科技联系 网站设计百度推广网站建设
  • 福州网站怎么做seo有哪些可以做问卷的网站
  • 怎样拥有自己的网站成都商城网站建设地址