Объект класса с двумя методами getOuter и getInner оборачивается другим классом, имеющим такой же интерфейс, но используется не наследование а композиция, т. е. объект вкладывается внутрь другого и они должны иметь независимые поля.
Известно, что из метода getOuter ровно один раз вызывается метод getInner. Надо сделать так, чтобы вызывался getInner не оборачиваемого объекта, а оборачивающего. В качестве прокси используется класс Wrapper, от которого наследуются обрачивающие классы. Что надо в него дописать, чтобы работало соответствующим образом?
Желаемый вывод после дописывания врэппера:
outer
c
b
a
(
class A {
constructor() {
this.x = 'A';
this.a = 'a';
}
getOuter() {
console.log('outer');
return `(${this.getInner()})`;
}
getInner() {
console.log('a');
return this.x + this.a;
}
}
var a = new A
class Wrapper {
constructor(original) {
this.original = original
}
getOuter() {
return this.original.getOuter();
}
getInner() {
return this.original.getInner();
}
}
class B extends Wrapper {
constructor(original) {
super(original);
this.x = 'B';
this.b = 'b';
}
getInner() {
console.log('b');
return `[${this.x}${this.b}][${super.getInner()}]`;
}
}
var b = new B(a);
class C extends Wrapper {
constructor(original) {
super(original);
this.x = 'C';
this.c = 'c';
}
getInner() {
console.log('c');
return `<${this.x}${this.c}><${super.getInner()}>`;
}
}
var c = new C(b);
console.log(c.getOuter());
Ответ
Ура, кажется получилось!
Надо в getOuter в оборачиваемый инстанс сохранить забинженный метод getInner текущего класса, в когда тот вызовет super.getInner, то эту ссылку затереть и продолжить вызывать по цепочке:
class A {
constructor() {
this.x = 'A';
this.a = 'a';
}
getOuter() {
console.log('outer');
return `(${this.getInner()})`;
}
getInner() {
console.log('a');
return this.x + this.a;
}
}
var a = new A
class Wrapper {
constructor(original) {
this.original = original
}
getOuter() {
this.original.getInner = this.getInner.bind(this);
return this.original.getOuter();
}
getInner() {
delete this.original.getInner;
return this.original.getInner();
}
}
class B extends Wrapper {
constructor(original) {
super(original);
this.x = 'B';
this.b = 'b';
}
getInner() {
console.log('b');
return `[${this.x}${this.b}][${super.getInner()}]`;
}
}
var b = new B(a);
class C extends Wrapper {
constructor(original) {
super(original);
this.x = 'C';
this.c = 'c';
}
getInner() {
console.log('c');
return `<${this.x}${this.c}><${super.getInner()}>`;
}
}
var c = new C(b);
console.log(c.getOuter());
Комментариев нет:
Отправить комментарий