为何setTimeout中仅能以委托方式调用this.MarkContents_Input?A可行B不可行原因
为啥箭头函数能调用
this.MarkContents_Input(),普通函数却不行? 哥们,太懂你搜三天找不到答案的憋屈了!我之前踩过无数this绑定的坑,刚好能给你掰扯清楚核心原因:
核心问题:JavaScript里this的绑定规则不一样
方案A用箭头函数的情况:
你写的setTimeout(() => this.MarkContents_Input(...))里,箭头函数不会创建自己的this上下文!它会直接继承外层函数refreshInputStatistics里的this——也就是你的类实例对象,所以自然能正常调用实例上的MarkContents_Input()方法。方案B用普通函数的情况(我猜你是这么写的):
如果换成普通函数当回调,比如setTimeout(function() { this.MarkContents_Input(...) }, 0),这里的this是调用时绑定的。setTimeout在执行回调时,默认会把this绑定到全局对象(浏览器里是window,Node环境是global),根本不是你的类实例,自然找不到MarkContents_Input这个方法,肯定报错。
为啥你感觉“只能用委托方式”?
其实你说的“委托”就是绑定this的手段,除了箭头函数,还有两种常用方式能达到同样效果:
- 用
bind()手动绑定:
把回调函数的setTimeout(function() { this.MarkContents_Input(this.vc.returnEditor(staticEditorDirective.textAreaEnum.Left)); }.bind(this), 0);this强行绑定到当前类实例上。 - 提前存
this到变量:
用refreshInputStatistics(): void { const that = this; // 先把实例的this存起来 this.updateprocessing(); setTimeout(function() { that.MarkContents_Input(that.vc.returnEditor(staticEditorDirective.textAreaEnum.Left)); }, 0); }that代替回调里的this,直接访问外层的实例。
代码对比更直观
可行的方案A:
refreshInputStatistics(): void { this.updateprocessing(); setTimeout(() => this.MarkContents_Input(this.vc.returnEditor(staticEditorDirective.textAreaEnum.Left)), 0); }
不可行的方案B(普通函数回调):
refreshInputStatistics(): void { this.updateprocessing(); setTimeout(function() { // 这里的this是全局对象,不是你的类实例! this.MarkContents_Input(this.vc.returnEditor(staticEditorDirective.textAreaEnum.Left)); }, 0); }
说白了就是箭头函数帮你省了手动绑定this的步骤,直接继承外层的上下文,而普通函数的this得看调用时机——setTimeout的调用环境刚好不指向你的实例,所以就跪了。
内容的提问来源于stack exchange,提问作者Jonathan Applebaum
相关产品推荐
相关产品推荐

