Не получается навесить setter для дочерних объектов

Класс:

class MyClass {
  constructor() {
    /**
     * Приватное свойство
     * По умолчанию нет родителя, т.е. является родителем
     */
    let parent = null;

    /**
     * По изменинию данного св-ва мы понимаем, что объект родителя изменился
     */
    this.property = undefined;


    /**
     * Получить значение родителя
     */
    this.getParent = () => parent;

    /**
     * Устанавливаем родителя и следим за некоторым свойством.
     */
    this.setParent = child => {
      parent = child;

      if (parent) {
        Object.defineProperty(parent, 'property', {
          set: () => {
            if (parent.property !== this.property) {
              this.property = parent.property;
            }
          },
        });
      }

      return this;
    };

  }
}

const cl1 = new MyClass();
const cl2 = new MyClass();
const cl3 = new MyClass();

cl2.setParent(cl1);
cl3.setParent(cl1);

// меняем значение
cl1.property = 1;

console.log(cl2.property);
// В выводе должно быть 1

console.log(cl3.property);
// В выводе должно быть 1

Проблема заключается в следующем. Когда у родителя много детей и при изменении родителя, срабатывает сеттер только у последнего ребёнка. Почему так? И как исправить данную проблему?


Ответы (1 шт):

Автор решения: Eugene Pavlyuk

Вы презаписываеете свойство через defineProperty поэтому у вас остаётся только последний сеттер.

Сеттер не копирует присваеваемое значение автоматически, то есть нужно так чтобы что-то изменилось:


    Object.defineProperty(parent, 'property', {
     set: val => {
       this.property = val;
     },
    });

Наверное нужно сохранять детей в массиве у родителя, и хранить значение property в приватном свойстве.

class MyClass {

    set property(val) {
        this._property = val;
        this.childs.forEach(child => child.property = this.property);
    }

    get property() { return this._property }

    constructor() {

        this.parent = null; 
   
        this.childs = [];
    }

    getParent() { return this.parent }


    setParent(parent) {
        this.parent = parent;
        parent.childs.push(this);
    }

}

const cl1 = new MyClass();
const cl2 = new MyClass();
const cl3 = new MyClass();

cl2.setParent(cl1);
cl3.setParent(cl1);


cl1.property = 1;

console.log(cl2.property);
   
console.log(cl3.property);

→ Ссылка