Search code examples
javascriptprivateecmascript-nextclass-fields

Accessing protected fields of base class from derived (ES2019 private class)


I'd like to access private fields of base class from derived classes without making them public (what is called 'protected' in other languages).

Consider the following class:

class Animal {

  #privateProp;

  constructor() {

  this.#privateProp = 12;

  }
}

Now the extending class:

class Cat extends Animal {

  constructor() {

    super();
  }

  doIt() {

    console.log(this.#privateProp) // 1 below
    console.log(super.#privateProp) // 2 below
  }
}

I'd like to execute as if it was protected:

new Cat().doIt();

But gets (respectively):

  1. Uncaught SyntaxError: Private field '#privateProp' must be declared in an enclosing class
  2. Uncaught SyntaxError: Unexpected private field

Notice that this code would work perfectly when privateProp becomes public, But I want to achieve a protected like behavior and get access to the 'private' fields like any language that support inheritance.

Any help will be appreciated.


Solution

  • you can create a private property with getter and setter methods having restricted access by checking if the constructor is not of the parent class itself.

    class Animal {
      #privateProp = 12;
      set Prop(val) {
        if (this.constructor.name !== 'Animal')
          return this.#privateProp = val;
        throw new Error('Cannot Access Protected property');
      }
      get Prop() {
        if (this.constructor.name !== 'Animal')
          return this.#privateProp;
        throw new Error('Cannot Access Protected property');
      }
    }
    
    class Cat extends Animal {
      get Prop() {
        return super.Prop;
      }
    
      set Prop(val) {
        super.Prop = val
      }
    }
    
    let cat = new Cat();
    console.log(cat.Prop)
    cat.Prop = 22
    console.log(cat.Prop)
    
    console.log(new Animal().Prop);