Using ‘this’ in a getter/setter defined on a class field property. How to define class field getters/setters on child properties?

The issue in question relates to human readability and data organization. I would like to assign getters and setters as children of class field properties, however I can’t get this to reference the class prototype data. I think this is the same problem solved by using self in a class constructor, but applied to class fields instead. Is there a comparable solution for class fields that would keep these definitions out of the constructor?

This is the format I would like to achieve. The constructor is not invoked because external data is not required for these field definitions. This throws a recursion error.

class data_controller {
  // class fields
  id = 12;
  a = 10;
  b = 20;
  // log data entries
  log = {
    entry: {
      get a() {
        return {
          id: this.id,
          value: this.a,
          label: 'a',
        };
      },
      get b() {
        return {
          id: this.id,
          value: this.b,
          label: 'b',
        };
      },
    },
  };
  // update data
  update = {
    set a(value) {
      this.a = value;
    },
    set b(value) {
      this.b = value;
    },
  };
}
// class usage
const data = new data_controller();
console.log(data.log.entry.a);
console.log(data.log.entry.b);
data.update.a = 50;
data.update.b = 60;
console.log(data.log.entry.a);
console.log(data.log.entry.b);

This is the format using ‘self’ and the constructor. I would like to keep the constructor free of these definitions.

class data_controller {
  // class fields
  id = 12;
  a = 10;
  b = 20;
  log = {};
  update = {};
  constructor() {
    self = this;
    // log data entries
    this.log.entry = {
      get a() {
        return {
          id: self.id,
          value: self.a,
          label: 'a',
        };
      },
      get b() {
        return {
          id: self.id,
          value: self.b,
          label: 'b',
        };
      },
    };
    // update data
    this.update = {
      set a(value) {
        self.a = value;
      },
      set b(value) {
        self.b = value;
      },
    };
  }
}
// class usage
const data = new data_controller();
console.log(data.log.entry.a);
console.log(data.log.entry.b);
data.update.a = 50;
data.update.b = 60;
console.log(data.log.entry.a);
console.log(data.log.entry.b);

This is a format which keeps the constructor free of definitions but does not implement the getter/setter class usage.

class data_controller {
  // class fields
  id = 12;
  a = 10;
  b = 20;
  // log data entries
  log = {
    entry: {
      a: () => {
        return {
          id: this.id,
          value: this.a,
          label: 'a',
        };
      },
      b: () => {
        return {
          id: this.id,
          value: this.b,
          label: 'b',
        };
      },
    },
  };
  // update data
  update = {
    a: (value) => {
      this.a = value;
    },
    b: (value) => {
      this.b = value;
    },
  };
}
// class usage
const data = new data_controller();
console.log(data.log.entry.a());
console.log(data.log.entry.b());
data.update.a(50);
data.update.b(60);
console.log(data.log.entry.a());
console.log(data.log.entry.b());

I believe I could also solve this issue by making the class field organization flat, but I would like to maintain multi-level structures.