简体   繁体   中英

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.

Fields are private in a similar way to how variables are block-scoped; if a property is private to a certain class , it may only be referenced inside that class. If you extend the class, it won't be visible in the derived class.

You could make a getter/setter on the superclass, if you want to be able to do stuff with it from the subclass:

 class Animal { #privateProp = 12; setProp(val) { this.#privateProp = val; } getProp() { return this.#privateProp; } } class Cat extends Animal { doIt() { console.log(this.getProp()); } } new Cat().doIt();

Another way is to define the "private" field as a WeakMap scoped only to the class declarations instead:

 const { Animal, Cat } = (() => { const privateProps = new WeakMap(); class Animal { constructor() { privateProps.set(this, 12); } } class Cat extends Animal { doIt() { console.log(privateProps.get(this)); } } return { Animal, Cat }; })(); new Cat().doIt();

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM