普通函数调用时this指向全局对象或undefined;箭头函数不绑定this,继承外层词法作用域;对象方法中this指向调用者,赋值后退化为普通调用;DOM事件中默认指向触发元素;call/apply/bind可显式控制this;new调用时this指向新实例;类方法遵循常规规则,但异步回调易丢失this。
在非严格模式下,function foo() { console.log(this); } 直接调用 foo(),this 指向 window(浏览器)或 globalThis(Node.js);严格模式下则为 undefined。这是最容易误判的起点——它和定义位置无关,只看「谁调用」。
this,它继承外层作用域的 this 值,无法通过 call/apply/bind 修改this 指向调用该方法的对象,但一旦把方法赋值给变量(如 const fn = obj.method;),再调用就退化为普通函数调用this 默认指向触发事件的元素(event.currentTarget),但若用箭头函数写法,则 this 是外层词法作用域的值,不是元素本身这三个方法本质都是手动指定函数执行时的 this 值。区别在于参数传递方式:call 接逗号分隔参数,apply 接数组
,bind 返回新函数(this 被固化,后续调用不可再改)。
bind 返回的函数如果是箭头函数,则 this 仍由外层决定,bind 无效new Foo())时,this 指向新创建的实例,此时 call/apply 会被忽略constructor 和普通方法默认是“非箭头函数”,所以 this 行为符合常规对象方法规则箭头函数没有自己的 this,它从定义时所在的作用域链中向上查找 this 值,并永久绑定。这意味着你不能用 call 改变它,也不能用 new 实例化它(会报 TypeError: Arrow functions are not constructors)。
const obj = {
name: 'test',
regular() {
return this.name; // 'test'
},
arrow: () => {
return this.name; // undefined(全局作用域中 this 没有 name)
},
wrapper() {
const innerArrow = () => this.name;
return innerArrow(); // 'test' —— 因为外层 regular 的 this 是 obj
}
};
类方法内部的 this 指向实例没问题,但一旦传入定时器、事件监听或 Promise 回调,就可能丢失。常见修复方式有三种:在 constructor 中用 bind、使用箭头函数属性(handleClick = () => { ... })、或在 JSX 中内联调用(onClick={() => this.handleClick()})。
this 已存在,但某些初始化逻辑(如 super() 后才有的属性)可能尚未赋值event,又想保持 this 指向实例,优先选 bind 或类字段箭头函数,避免内联