Svelte 中使用 class 时 setTimeout 首次执行后应用报错崩溃问题
问题原因
这个问题并非Svelte框架导致,本质是JavaScript中普通函数的this动态绑定规则造成的:
- 首次直接调用
cs.zeroToOne()时,函数的this会绑定到调用它的cs实例上,因此可以正常访问实例上的getOne方法。 - 当你把
this.zeroToOne作为参数传递给setTimeout时,相当于将这个函数单独脱离了实例上下文,定时器触发函数执行时没有绑定调用主体,此时非严格模式下this会指向全局对象,严格模式下this为undefined,两者都不存在getOne方法,因此抛出对应错误。
解决方法
下面是3种常用的可行方案,可根据场景选择:
1. 箭头函数包裹调用(最常用)
箭头函数的this继承自外层作用域的this,此处外层就是类实例的上下文,不会出现绑定丢失的问题:
// ClassSample.js 中修改zeroToOne方法 zeroToOne() { console.log(this.getOne()); // 用箭头函数包裹方法调用 setTimeout(() => this.zeroToOne(), 50); }
2. 显式用bind绑定上下文
通过bind方法手动将函数的this永久绑定到当前实例,再传给定时器:
zeroToOne() { console.log(this.getOne()); setTimeout(this.zeroToOne.bind(this), 50); }
如果该方法需要多次传递调用,也可以在构造函数内提前完成绑定:
constructor (_zero, _one) { this.zero = _zero; this.one = _one; // 构造函数内统一绑定方法上下文,后续无需重复bind this.zeroToOne = this.zeroToOne.bind(this); }
3. 类方法定义为箭头函数字段
如果你的开发环境支持类公共字段语法,可直接将方法定义为箭头函数,它的this会默认绑定到实例:
zeroToOne = () => { console.log(this.getOne()); setTimeout(this.zeroToOne, 50); }
该方案写法最简洁,仅需要注意箭头函数方法是挂载在每个实例上,而非原型链上,普通业务场景下性能差异可以忽略。
内容的提问来源于stack exchange,提问作者Gnai Hari
相关产品推荐
相关产品推荐

