避免this丢失的关键是控制调用上下文:①用箭头函数继承外层this;②用bind提前永久绑定;③用that/self缓存this;④避免直接传递未绑定方法。

在对象方法中避免 this 丢失,关键在于理解“调用方式决定 this”,而不是“定义位置”。当方法被抽离出来单独调用(比如赋值给变量、传入 setTimeout 或事件监听器),隐式绑定就断开了,this 就会退回到默认绑定——非严格模式下是 window,严格模式下是 undefined。解决它不靠猜,而靠控制调用上下文。
用箭头函数捕获外层 this
箭头函数没有自己的 this,它直接继承定义时所在函数作用域的 this 值。适合写在对象方法内部,用于封装回调逻辑。
- 在对象方法里定义箭头函数,它的 this 就等于该方法执行时的 this(即对象本身)
- 常见于
setTimeout、Promise.then、数组遍历回调等场景 - 注意:不能用于需要动态 this 的场合(比如想让方法能被其他对象复用)
示例:
const obj = { name: 'Alice', sayHi() { setTimeout(() => { console.log(`Hello, ${this.name}`); }, 100); } }; obj.sayHi(); // 正确输出 "Hello, Alice"提前用 bind 绑定 this
在构造函数或初始化阶段,对方法调用 .bind(this),生成一个永久绑定 this 的新函数。适合类组件、控制器类等需要稳定上下文的场景。
- 绑定后可反复传入事件监听器、定时器、高阶函数,无需每次处理
- 比箭头函数更明确,也避免了频繁渲染时重复创建函数的问题
- 适用于需要兼容老环境或明确控制参数预设的情况
示例:
class Counter { constructor() { this.count = 0; this.handleClick = this.handleClick.bind(this); } handleClick() { this.count++; console.log(this.count); } init() { document.getElementById('btn').addEventListener('click', this.handleClick); } }用 that / self 缓存 this 引用
在方法开头用 const that = this 或 const self = this 保存当前上下文,后续所有回调都使用该变量访问对象属性或方法。
- 兼容性最好,所有 JS 环境都支持
- 语义清晰,调试时容易追踪
- 缺点是多了一行样板代码,且需确保缓存时机正确(必须在 this 还有效时)
示例:
const obj = { name: 'Bob', greet() { const that = this; setTimeout(function() { console.log(`Hi from ${that.name}`); }, 200); } };避免直接传递未绑定的方法
不要把对象方法直接当作回调传出去,例如 obj.handleClick 或 arr.forEach(obj.method) —— 这类写法几乎必然导致 this 丢失。
- 改用箭头函数包装:
() => obj.handleClick() - 或显式绑定:
obj.handleClick.bind(obj) - 数组方法如
map、filter支持第二个参数指定 this:arr.map(callback, obj)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











