旧版javascript中需用self = this捕获this以解决回调中this丢失问题,因其不继承外层作用域而由调用方式决定,适用于事件监听、定时器等场景,现代推荐箭头函数但兼容老旧环境时仍需此模式。

在旧版 JavaScript(ES5 及更早)中,this 的指向容易因函数调用方式改变而丢失,尤其在事件回调、定时器或异步操作中。闭包捕获 self = this 是一种经典且有效的解决方式——它把当前上下文的 this 保存为一个变量,在内部函数中稳定引用。
为什么需要 self = this
在非箭头函数中,this 不继承外层作用域,而是由调用方式决定。比如:
当方法被单独提取使用时:
const handler = obj.handleClick;<br>
button.addEventListener('click', handler); // 此时 handler 中的 this 指向 button,而非 obj
闭包通过在外层函数作用域中缓存 this,让内层函数能始终访问原始对象。
基本写法:用 var self = this 捕获
在方法开头声明变量保存当前 this,后续回调中使用该变量:
- 确保在函数体最开始赋值,避免逻辑分支导致遗漏
- 变量名常用
self、that或_this,语义清晰即可 - 适用于普通函数、对象方法、构造函数中的原型方法
示例:
function Counter() {<br>
this.count = 0;<br>
var self = this; // 捕获当前实例<br><br>
this.increment = function() {<br>
self.count++; // 使用 self,而非 this<br>
};<br><br>
setTimeout(function() {<br>
console.log('count:', self.count); // 正确输出 0<br>
}, 100);<br>
}
常见场景与注意事项
该模式广泛用于以下情况:
- DOM 事件监听器中需访问组件实例(如 jQuery 插件、原生类封装)
- Node.js 回调(如
fs.readFile)中维持上下文 - 循环中为每个元素绑定不同数据的事件处理器
注意点:
- 不要在箭头函数内部再用
self = this——箭头函数本就不会绑定自己的this,直接用this即可 - 若已用
bind()或call()显式绑定,通常无需额外捕获 - 现代代码推荐优先使用箭头函数或 class 字段语法(
onClick = () => {}),但维护旧项目时仍需理解此模式
替代方案对比(简要)
虽然 self = this 简单直接,但还有其他方式可选:
-
func.bind(this):明确绑定,但每次调用都新建函数,可能影响性能或事件移除 -
Function.prototype.call/apply:适合一次性调用,不适用于长期持有回调 - ES6+ 的箭头函数:自动继承外层
this,最简洁,但不兼容 IE
在必须支持老旧运行环境(如 IE8–9)的项目中,self = this 仍是可靠首选。











