this是函数调用时引擎动态注入的执行上下文属性,值仅由调用方式决定,一旦写入即固定不变;隐式绑定丢失、默认绑定陷阱、严格模式影响、显式绑定例外及箭头函数静态捕获均源于此机制。

从执行上下文底层看,this 不是变量、不存于词法环境(LexicalEnvironment)、也不在变量环境中(VariableEnvironment),它是一个独立的、由引擎在函数调用时**动态注入的执行上下文属性**(ThisBinding)。每次函数进入执行阶段,引擎会根据调用方式,在该函数的执行上下文记录(ExecutionContext Record)中直接写入 this 值——这个值一旦写入,就固定不变,后续任何作用域查找都不会影响它。
隐式绑定丢失:对象方法一“摘出来”就失效
这是日常开发里最高频的致命坑。函数作为对象属性被调用时(obj.method()),引擎识别出「隐式绑定」,把 this 设为 obj;但只要函数被赋值、传参或解构,就脱离了对象调用链,变成独立调用,this 立即回退到默认绑定。
-
const fn = obj.method; fn();→this是window(非严格)或undefined(严格) -
setTimeout(obj.method, 100);→ 浏览器内部以独立方式调用,this丢失 -
const { method } = obj; method();→ 解构后调用,同样触发默认绑定
回调函数中的 this 默认绑定:事件监听和 Promise 都中招
浏览器 API(如 addEventListener、setTimeout、Promise.then)内部调用回调时,不带任何对象前缀,属于典型的「默认绑定」场景。哪怕你传的是类实例方法,执行时也与原对象无关。
-
btn.addEventListener('click', this.handleClick);→ 点击触发时,this指向btn?错,是window或undefined -
fetch('/api').then(this.handleSuccess);→handleSuccess执行时this已不可用 - React/Vue 类组件中未绑定的事件处理器,首次渲染正常,交互后报
Cannot read property 'xxx' of undefined
严格模式下默认绑定直接报错,而非静默失败
非严格模式中,this 指向 window,可能意外访问到全局变量(比如 var a = 1 后,function f() { return this.a } 返回 1);但严格模式下,this 为 undefined,任何对 this.xxx 的读取都会立即抛 TypeError。
- 模块文件默认启用严格模式(ES6 modules),所以 import 的工具函数若含
this,极易爆错 - 箭头函数虽无
this,但若它内部调用普通函数,那个普通函数仍受严格模式约束 - Node.js 中的 CommonJS 模块不自动严格,但搭配 TypeScript 编译或 ESLint 规则后常被强制开启
显式绑定被中间层覆盖:call/apply/bind 并非绝对安全
call/apply/bind 属于「显式绑定」,优先级高于隐式和默认绑定,但有两个关键例外:
- 当使用
bind创建的函数再被new调用时,this绑定被忽略,改走 new 绑定规则(返回新实例) - 如果显式绑定传入
null或undefined,引擎会跳过它,回落到默认绑定(非严格下是window) - 第三方库(如 Lodash 的
debounce)内部若未正确保留this,会导致你 bind 好的方法再次丢失上下文
箭头函数的 this 是“冻结快照”,不是“继承”
箭头函数没有自己的 this,它在定义时就捕获外层普通函数执行上下文中的 this 值,并固化下来。这不是动态查找,也不是作用域链查找,而是编译期就确定的静态绑定。
-
const obj = { name: 'a', fn: () => console.log(this.name) };→this是定义时所在上下文(通常是全局),不是obj - 在类中写
handler = () => {...}字段语法,本质是构造函数中用当前实例this初始化箭头函数,所以能安全使用 - 但若在定时器里嵌套箭头函数:
setTimeout(() => { setTimeout(() => console.log(this), 0) }, 0),最外层的this决定了所有内层箭头函数的this,无法中途切换
本质上,所有坑都源于一个事实:this 的值只取决于函数**如何被调用**,而底层执行上下文记录中,this 字段在函数开始执行那一刻就被写死。它不关心你在哪写的函数,也不关心它被谁引用,只认调用现场的语法结构。理解这一点,比背口诀更可靠。

















