-
Notifications
You must be signed in to change notification settings - Fork 136
Description
Although cloning objects with private ('hash name') properties works, any subsequent method calls that access such a property will produce a TypeError along the lines of Cannot write private member #val to an object whose class did not declare it.
For example:
class Counter {
#val = 0;
inc() { return this.#val++; }
}
let counter = new Counter();
let cloned = clone(counter); // All is still good
console.log(counter.inc()); // 0
console.log(cloned.inc()); // TypeError
It's obvious in this example because everything is so close together, but if the cloning and the violating method call are far apart, it can be extremely hard to track down - especially since cloned instanceof Counter === true, so it looks like it should work: cloned is of the right "type" and the access happens inside a method of Counter.
I think this is probably caused by the fact that the constructor is never invoked when cloning, which seems to be a prerequisite for private properties to work. To illustrate, with the above example:
let created = Object.create(Counter.prototype);
console.log(created.inc()); // TypeError
I'm not sure if there is a way around it. Even if there is (as far as the TypeError is concerned), I strongly doubt that actually cloning these values is possible even with advanced magic, seeing how their inaccessibility from code external to the declaring class is sort of the whole point.
But it might be worthwhile adding a note to this effect to the docs.
TL;DR: I suggest adding a note to the documentation that cloning instances of a class that has private members will lead to a late fail on any method calls that access such a member.