覆盖Javascript中的类变量
我做了一个班级服务。我正在尝试每 X 秒运行一次 Interval。默认值为 30 秒。但我想在其他课程中设置自定义延迟。我找不到覆盖父类中变量的方法。
class Service {
delay = 30;
constructor(api, client = undefined) {
this.api = api;
this.client = client;
this.handle();
}
getMiliSeconds() {
return this.delay * 1000;
}
service = async () => {
// Service to run in background
}
handle() {
setInterval(() => { this.service() }, this.getMiliSeconds());
}
}
module.exports = Service;
当我扩展类 Service 时,我试图覆盖delay变量
class Notification extends Service {
delay = 60;
service = async () => {
// I am not running every 60 seconds.
}
}
module.exports.Notification = Notification;
然而,间隔函数仍然每 30 秒运行一次。而不是我在 Notifications 类中设置的 60 秒。
回答
问题是超级构造函数在子构造函数运行或分配给实例之前运行。例如:
class Parent {
prop = 'foo'
constructor() {
console.log(this.prop);
}
}
class Child extends Parent {
prop = 'bar'
}
class Parent {
prop = 'foo'
constructor() {
console.log(this.prop);
}
}
class Child extends Parent {
prop = 'bar'
}
将始终记录foo,因为类字段prop = 'bar'只会在父构造函数完成并且控制流返回给子构造函数后运行。
当您调用this.handle超级构造函数时,getMiliSeconds立即运行,在子代有机会将自己的构造函数分配delay给实例之前检索延迟。
为了修复它,我将this.handle移出构造函数,以便可以在对象完全实例化之后(而不是之前)按需调用它。
在下面的片段中,delay = 1子类中的 现在成功地使子服务每秒运行一次,而不是每 3 秒一次。
另一种方法是将delay属性放在原型上,而不是作为类字段(相当于在构造函数内部 - 并且允许相关构造函数运行的时间是问题):
class Service {
delay = 3;
constructor(api, client = undefined) {
this.api = api;
this.client = client;
}
getMiliSeconds() {
return this.delay * 1000;
}
service = async () => {
console.log('parent service');
// Service to run in background
}
handle() {
setInterval(() => { this.service() }, this.getMiliSeconds());
}
}
class Notification extends Service {
delay = 1;
service = async () => {
console.log('child service');
}
}
const n = new Notification();
n.handle();