递归函数中this指向取决于调用方式而非递归本身;箭头函数可继承外层this;推荐类中用箭头函数属性或显式绑定(call/apply/bind);更健壮做法是将状态作为参数传入递归函数。

在递归函数中,this 的指向不会自动“维持”,它取决于每次函数调用时的调用方式,而不是递归本身。也就是说,this 始终由**谁调用该函数**决定,递归只是函数自己调用自己,但每次调用仍遵循 JavaScript 的 this 绑定规则。
箭头函数自动捕获外层 this
箭头函数不绑定自己的 this,而是继承定义时所在词法作用域的 this。如果递归函数是箭头函数,或内部用箭头函数递归,就能自然保持外层对象的 this。
✅ 推荐场景:类方法中写递归逻辑
- 把递归逻辑写成类内的箭头函数属性(如
handleClick = () => { ... this.handleClick(); ... }) - 或在普通方法内用箭头函数封装递归调用:
const recur = () => { /* 使用 this */; recur(); };
显式绑定 this(call / apply / bind)
如果必须用普通函数递归,每次调用时手动传入 this,可确保上下文一致。
- 用
func.call(this, ...args)或func.apply(this, args)显式指定 - 提前用
const self = this;缓存,递归中直接使用self(传统但有效) - 构造时用
bind(this)绑定函数(适合一次性绑定,注意避免重复 bind)
避免依赖 this 的递归设计
更健壮的做法是让递归函数成为纯函数或接收必要参数,把依赖的数据显式传入,而非隐式依赖 this。
- 把需要的状态(如 DOM 元素、配置、计数器)作为参数传入递归函数
- 例如:
function traverse(node, context) { /* 处理 node,再调用 traverse(child, context) */ } - 这样既利于测试,也彻底规避 this 绑定问题
常见陷阱:事件回调 + 递归 + this 丢失
比如在事件处理中启动递归,但递归调用的是普通函数,容易因调用方式改变导致 this 变成 undefined(严格模式)或全局对象。
- 错误写法:
onClick() { this.doWork(); } → doWork() { this.data++; this.doWork(); } // 第二次 this 可能丢失 - 修复方式:改用箭头函数、bind、或缓存 this(
const that = this;)











