Object.create() and native private fields

Viewed 339

When I create instance of a class via Object.create(Example.prototype) to bypass its constructor, it is no longer possible to work with native private fields:

class Example {
  #myPrivateProp;

  setup() {
    this.#myPrivateProp = 1;
  }
}

const e1 = new Example();
const e2 = Object.create(Example.prototype);
console.log(e1.setup()); // works
console.log(e2.setup()); // fails with Uncaught TypeError: Cannot write private member #myPrivateProp to an object whose class did not declare it

Is there a way to make this work, while maintining the invariant of not calling the constructor?

For context you can see this issue: https://github.com/mikro-orm/mikro-orm/issues/1226

1 Answers

What you are defining here is not a private field but a private instance field. A private instance field is there not to be exposed and manipulated by others except that very instance. You shouldn't be able to clone that very instance along with it's state, manipulate it and replace the original one.

You have two options;

  1. A static private field that belongs to the Example class which can be accessed and manipulated mutually by any instance of that class or even by objects created like Object.create(Example.prototype).

such as;

class Example {
  static #SECRET = 0;
  constructor(){
  }

  addOne() {
    return ++Example.#SECRET;
  }
}


i1 = new Example();
i2 = new Example();
console.log(i1.addOne()); // <- 1
console.log(i2.addOne()); // <- 2
i3 = Object.create(Example.prototype);
console.log(i3.addOne()); // <- 3
Example.#SECRET = 4;      // <- Uncaught SyntaxError: Private field '#SECRET' must be
                          //    declared in an enclosing class
  1. The private instance field belongs to the instance and can only be accessed and manipulated by that very instance. How this is achieved is exactly seen in your example code. Every single instance will have it's own #myPrivateProp which, if you ask me, is a beautiful thing. For example one can instantiate many individual Queues and their operationaly critical properties wouldn't be exposed.
Related