Я думаю, что следующий (упрощенный) код должен работать:
class WfConfigurable {
constructor(config) {
this._init(config);
}
_init(config) {
this.configure(config);
}
configure(config) {}
}
class WfStateful extends WfConfigurable {
#saveSuspend = 0;
constructor(config) {
super(config);
}
get saving() { return this.#saveSuspend == 0; }
configure(config) {
this.suspendSave();
super.configure(config);
this.continueSave();
}
suspendSave() {
this.#saveSuspend++;
}
continueSave(force) {
if (force) {
this.#saveSuspend = 0;
} else {
this.#saveSuspend = Math.max(this.#saveSuspend - 1, 0);
}
}
}
class WfApp extends WfStateful {
constructor(config) {
super(config);
}
}
const wfApp = new WfApp({});
Но я получил следующее сообщение об ошибке:
Ошибка типа: невозможно прочитать частный член #saveSuspend из объекта, класс которого его не объявил
в WfApp.suspendSave ((индекс):24:13)
в WfApp.configure ((индекс):19:14)
в WfApp._init ((индекс):7:14)
в новом WfConfigurable ((индекс): 4:14)
в новом WfStateful ((индекс):15:9)
в новом WfApp ((индекс):37:9)
в (индекс):41:15
Например, это хорошо работает:
class A {
#priv = 'hello';
constructor() {
console.info('A');
}
get priv() {
return this.#priv;
}
set priv(p) {
this.#priv = p;
}
}
class B extends A {}
const b = new B();
b.priv += ' babe';
console.info(b.priv);
Пишет: «привет, детка»
Частные свойства не наследуются, поэтому экземпляр подкласса не может получить доступ к свойствам даже через код родительского класса.
@DanielA.White Не думаю, что это поможет, но я добавил стек ошибок.
Что на самом деле делает configure
? Почему бы просто не сделать это в своем конструкторе?
@Bergi В этом упрощенном коде он ничего не делает. Но в реальном коде он настроит объект, и я хочу сделать его вызываемым отдельно, даже после времени создания.
Сообщение об ошибке «Невозможно прочитать закрытый член #saveSuspend
из объекта, класс которого не объявил его» немного сбивает с толку. Более точным в этом случае было бы «из объекта, где он (еще) не инициализирован».
Частные поля и поля в целом создаются в экземпляре (и инициализируются значением, определенным в теле класса), когда конструктор super()
завершает работу. Если этот конструктор вызывает переопределенный метод (configure
) до завершения инициализации, он не сможет получить доступ к несуществующему полю. В случае с частными полями он просто выдает исключение, поскольку поле не существует, вместо того, чтобы возвращать undefined
, как обычное свойство.
Единственное решение — никогда не вызывать переопределяемый метод из конструктора. Это верно для любого языка. В вашем случае просто избавьтесь от метода configure
вообще, это не имеет значения.
Что такое стек ошибок?