最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
通过分析 V8 引擎执行上下文栈深刻看透 this 绑定的物理寻址内核
时间:2026-06-23 09:46:46 编辑:袖梨 来源:一聚教程网
this是函数调用时V8在栈帧ThisBinding字段直接写入的确定值,非变量或属性;四大绑定规则决定该字段初始化值,箭头函数无ThisBinding字段,setTimeout中obj.fn因脱离调用对象而触发默认绑定。
要真正看透 this 绑定,不能只记“谁调用谁是 this”,而得回到 V8 执行上下文栈的物理构建过程——this 不是变量,也不是属性,它是每个函数调用时,引擎在压入新栈帧(stack frame)那一瞬间,**直接写入当前执行上下文对象的 ThisBinding 字段的一个确定值**。
执行上下文栈是 this 的物理容器
V8 每次调用函数,都会在调用栈顶部创建一个全新的执行上下文对象。这个对象在内存中是一个结构化实体,包含三个核心字段:LexicalEnvironment、VariableEnvironment 和 ThisBinding。其中 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 值。所以它无法被 call、apply、bind 或 new 修改——不是被“保护”了,而是压根没这个字段可改。
为什么 setTimeout(obj.fn, 100) 会丢失 this?
因为 obj.fn 被取值后变成纯函数引用,传入 setTimeout 时已脱离 obj。当定时器触发回调时,V8 执行的是一个孤立函数调用,调用表达式里没有点号、没有 new、也没有显式绑定参数——只能走默认绑定。此时创建的新执行上下文,其 ThisBinding 字段被设为 undefined(严格模式)或 window(非严格),和原始 obj 再无关联。这不是“丢失”,而是上下文重建时,物理上就没写入那个对象。
相关文章
- 魅族20pro安兔兔能跑多少分 06-23
- 有哪些值得推荐的小众软件 良心的小众软件精选 06-23
- 哪个奢侈品app平台性价比最高 值得推荐的奢侈品app平台有哪些 06-23
- 汽车模拟驾驶软件都有哪些 好用的模拟驾驶软件推荐 06-23
- 便捷的手机制作表格软件盘点 实用的制表软件汇总 06-23
- 邮政快递包裹动态入口在哪 06-23