一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

通过分析 V8 引擎执行上下文栈深刻看透 this 绑定的物理寻址内核

时间:2026-06-23 09:46:46 编辑:袖梨 来源:一聚教程网

this是函数调用时V8在栈帧ThisBinding字段直接写入的确定值,非变量或属性;四大绑定规则决定该字段初始化值,箭头函数无ThisBinding字段,setTimeout中obj.fn因脱离调用对象而触发默认绑定。

要真正看透 this 绑定,不能只记“谁调用谁是 this”,而得回到 V8 执行上下文栈的物理构建过程——this 不是变量,也不是属性,它是每个函数调用时,引擎在压入新栈帧(stack frame)那一瞬间,**直接写入当前执行上下文对象的 ThisBinding 字段的一个确定值**。

执行上下文栈是 this 的物理容器

V8 每次调用函数,都会在调用栈顶部创建一个全新的执行上下文对象。这个对象在内存中是一个结构化实体,包含三个核心字段:LexicalEnvironmentVariableEnvironmentThisBinding。其中 ThisBinding 是独立字段,不参与作用域链查找,也不受 var/let 影响——它只由调用方式决定,并在上下文创建阶段就完成赋值。

这意味着:this 的值不是运行时“查出来”的,而是调用发生时被“塞进去”的。栈帧一旦形成,ThisBinding 就已固定,后续所有代码访问 this,本质就是读取该栈帧内存块中的那个字段。

四大绑定规则对应栈帧初始化动作

V8 在创建函数执行上下文前,会解析整个调用表达式,按优先级走一套硬编码逻辑,最终把计算结果直接写入 ThisBinding

  • new 绑定:遇到 new Foo(),V8 创建新对象,将其地址直接填入新上下文的 ThisBinding 字段
  • 显式绑定:遇到 fn.call(obj),V8 取第一个参数 obj(或 undefined),原样写入 ThisBinding
  • 隐式绑定:识别点号左侧最近的对象(如 obj.method() 中的 obj),将其引用写入 ThisBinding;中间链(如 a.b.c.method())完全不参与判断
  • 默认绑定:无上述匹配时,严格模式下写入 undefined,非严格模式写入 globalThis(浏览器即 window

箭头函数没有 ThisBinding 字段

箭头函数在 V8 编译阶段就被标记为“词法 this”,它根本不会创建自己的执行上下文 ThisBinding 字段。运行时访问 this,引擎直接沿词法环境链向上查找,复用外层**普通函数**执行上下文里的 ThisBinding 值。所以它无法被 callapplybindnew 修改——不是被“保护”了,而是压根没这个字段可改。

为什么 setTimeout(obj.fn, 100) 会丢失 this

因为 obj.fn 被取值后变成纯函数引用,传入 setTimeout 时已脱离 obj。当定时器触发回调时,V8 执行的是一个孤立函数调用,调用表达式里没有点号、没有 new、也没有显式绑定参数——只能走默认绑定。此时创建的新执行上下文,其 ThisBinding 字段被设为 undefined(严格模式)或 window(非严格),和原始 obj 再无关联。这不是“丢失”,而是上下文重建时,物理上就没写入那个对象。

热门栏目