It's stated in the FAQ that this.#x !== this['#x'] this makes sense in the same way that this.x.y !== this['x.y'], however that means we currently have no way of dynamic access.
That answer also gives the argument that dynamic access "is contrary to the notion of 'private'". This is not true at all, of course private fields shouldn't be dynamically accessed outside of the class body, but inside there are many reasons it can be valuable.
Not Possible Without Dynamic Access
I want to be clear here, I'm not advocating that private fields should be settable or retrievable from outside the class body, unless the library maintainer explicitly adds such feature.
-
Observer pattern
If I library were to have set(obj, key, value) and observe(obj, key, callback) methods there would be no way to internally observe or set private fields, this would necessitate anyone using such library to have all fields public.
-
Intentional Escape Hatch For Debug and Tests
Possible Solutions
I would like to open this up to discussion, I don't quite know myself the best way to make this possible, or all the concerns people have about introducing such a feature.
Just to get things started though one possibility might be a new Private Key type. A example might look something like:
class Cat {
#hunger = 0;
constructor () {
if (ENV.DEBUG_PRIVATE) {
this.__getPrivate = (privateKey) => this.#[privateKey];
// Set uses the observable `set` method
this.__setPrivate = (privateKey, value) => set(this, #[privateKey], value);
// If not using a observer library
// this.__setPrivate = (privateKey, value) => this.#[privateKey] = value;
}
observe(this, #['hunger'], () => {
if (this.#hunger > 10) {
this.growl();
}
})
setInterval(() => {
set(this, #['hunger'], this.#hunger + 1);
}, 1000);
}
growl () {
console.log('Meeooow');
}
eat (food) {
set(this, #['hunger'], this.#hunger - food.value);
}
}
const cat = new Cat();
// Private fields still directly innaccessible from outside class body
cat.#['hunger']; // throw error or return undefined
cat.#['hunger'] = 2; // throw error
set(cat, #['hunger'], 2); // throw error
cat.__getPrivate('hunger'); // return 0
cat.__setPrivate('hunger', 10); // return 10
// log > Meeooow
cat.eat({ name: 'fish', value: 3 });
cat.__getPrivate('hunger'); // return 7
Open to better ideas for the syntax
It's stated in the FAQ that
this.#x !== this['#x']this makes sense in the same way thatthis.x.y !== this['x.y'], however that means we currently have no way of dynamic access.That answer also gives the argument that dynamic access "is contrary to the notion of 'private'". This is not true at all, of course private fields shouldn't be dynamically accessed outside of the class body, but inside there are many reasons it can be valuable.
Not Possible Without Dynamic Access
I want to be clear here, I'm not advocating that private fields should be settable or retrievable from outside the class body, unless the library maintainer explicitly adds such feature.
Observer pattern
If I library were to have
set(obj, key, value)andobserve(obj, key, callback)methods there would be no way to internallyobserveorsetprivate fields, this would necessitate anyone using such library to have all fields public.Intentional Escape Hatch For Debug and Tests
Possible Solutions
I would like to open this up to discussion, I don't quite know myself the best way to make this possible, or all the concerns people have about introducing such a feature.
Just to get things started though one possibility might be a new Private Key type. A example might look something like:
Open to better ideas for the syntax