我正在尝试将我的 javascript 类从旧样式转换为新样式。问题是,对于新样式,JavaScript 要求在访问
super
之前在构造函数中调用 this
。我必须扩展一个我不是其所有者的类,并且在该构造函数中它调用一个方法,我在使用自己的属性的地方覆盖该方法。怎么解决?
class A {
constructor() {
this.create()
}
create() {}
reload() {
this.create()
}
}
class B extends A {
constructor(options) {
super()
this.options = options
}
create() {
let title = this.options.title // TypeError: Cannot read properties of undefined (reading 'title')
}
}
class A {
constructor(opts, arg) {
this.opts(opts);
console.log('prop in the parent constructor', this.p)
}
opts(opts){}
}
class B extends A {
constructor(opts, arg) {
super(opts, arg);
console.log('prop in the child constructor', this.p)
}
opts(opts){
console.log('before even constructor of class A called, this is called. Can be used to assign options')
Object.assign(this, opts)
}
}
let b = new B({
p: "my prop"
}, "some normal arg");
// you can also use it without any opts
console.log('---')
let c = new B({}, "some other arg");
这就是我喜欢为父类中需要的选项做的
我会在 B 的
create
中添加一个守卫,并让它的构造函数再次执行它:
class A {
constructor() {
this.create();
}
create() {
console.log("I don't want to run this");
}
reload() {
this.create();
}
}
class B extends A {
constructor(options) {
super();
this.options = options;
this.create(); // ... but now
}
create() {
if (!this.hasOwnProperty("options")) return; // not now...
let title = this.options.title;
console.log("title", title);
}
}
let b = new B({ title: "my title" });
console.log("let's reload");
b.reload();
我会让原型的
create
成为空操作,然后在 super()
完成后调用一个函数。
class A {
constructor() {
this.create()
}
create() {}
}
class B extends A {
constructor(options) {
super()
this.options = options
this.createB();
}
createB() {
const title = this.options.title;
console.log(title);
}
create() {}
}
new B({ title: 'foo' });
我想你也可以在超级运行后分配给
.create
,把它从无操作恢复到你想要的功能。
class A {
constructor() {
this.create()
}
create() {}
}
function createB() {
}
class B extends A {
constructor(options) {
super()
this.options = options
this.create = () => {
const title = this.options.title;
console.log(title);
};
this.create();
}
create() {}
}
new B({ title: 'foo' });