Angular中setInterval调用方法导致counterStart为NaN的问题
为什么setInterval调用Angular组件方法时this.counterStart变成NaN?
问题重现
组件代码如下:
export class GameControlComponent { @Output() counterUpdated = new EventEmitter<{counter: number, type: string}>(); @Output() counterStop = new EventEmitter(); counterSet: any; counterStart: number = 0; startCount() { console.log('counter is ' + this.counterStart); this.counterSet = setInterval(this.updateCount, 1000); //this.updateCount(); } updateCount() { this.counterStart += 1; console.log('New counter is ' + this.counterStart); this.counterUpdated.emit({ counter: this.counterStart, type: (this.counterStart % 2) === 0 ? 'even' : 'odd' }); }
HTML按钮绑定了(click)='startCount()',直接调用this.updateCount()时counterStart能正常更新,但用setInterval(this.updateCount, 1000)调用时,updateCount方法里的counterStart会变成NaN。而使用setInterval(this.updateCount.bind(this), 1000)则能正常运行。
原因分析
这是JavaScript中this上下文绑定导致的问题:
- 直接调用
this.updateCount()时,this指向当前的GameControlComponent实例,所以能正确访问实例上的counterStart属性。 - 当把
this.updateCount作为参数传给setInterval时,方法本身被单独传递,原有的this绑定会丢失。此时setInterval执行这个方法时,this默认指向全局对象(浏览器环境下是window),而window上不存在counterStart属性,所以this.counterStart是undefined,undefined + 1的结果就是NaN。
其他可行解决方案
除了使用bind(this)强制绑定上下文,还有两种常用处理方式:
- 箭头函数包裹调用:箭头函数会继承外层作用域的
this,也就是组件实例:
this.counterSet = setInterval(() => this.updateCount(), 1000);
- 构造函数提前绑定方法:
constructor() { this.updateCount = this.updateCount.bind(this); } // 后续直接传递方法即可 this.counterSet = setInterval(this.updateCount, 1000);
内容的提问来源于stack exchange,提问作者Yari Piras
相关产品推荐
相关产品推荐

