But it is an object property, just like everything else attached to "this".
That "this.foo" is not "this.#foo" that's because "foo" is a different key than "#foo".
But it is an object property, just like everything else attached to "this".
That "this.foo" is not "this.#foo" that's because "foo" is a different key than "#foo".
The current idea is that private fields are kinda like this:
export class Bar {
#foo = 100;
setFoo(value) {
this.#foo = value;
}
getFoo() {
return this.#foo;
}
getFooFromOtherBar(otherBar) {
return otherBar.#foo;
}
}
// similar to (but implemented differently I'm sure)
const barPrivate = new WeakMap(); // properties are only private if this is never exported
export class BarWithoutPrivateFields {
constructor() {
barPrivate.set(this, {});
barPrivate.get(this).foo = 100;
}
setFoo(value) {
barPrivate.get(this).foo = value;
}
getFoo() {
return barPrivate.get(this).foo;
}
getFooFromOtherBar(otherBar) {
return barPrivate.get(otherBar).foo;
}
}
It is NOT a property key! this["#foo"] = "Value A"
this.#foo = "Value B"
console.log(this["#foo"]) //=> "Value A"
console.log(this.#foo) //=> "Value B"
That's why people are saying that `this.#foo` is not an object property. You can think of it like one if you want, but it's not really the same thing.I know this is very non-constructive but reading through these threads and these proposed improvements to modern JS the expression "polishing a turd" pops up in my mind repeatedly. That people chose to bring this thing out of the browser to use as a general purpose language is rather baffling to me. I can't wait for WebAssembly to become more mainstream, then I'll be able to archive my little knowledge of JS deep into my brain, alongside Perl and TCL.
</nonconstructive rant>
You can't throw an error on `this["#foo"]` because then you'd be publicly exposing the fact that a private field `this.#foo` exists.
But just “knowing they exist” is not causing any pain for a library developer, as long as they can’t read the value. So I don’t understand the need to also hide the fact they exist. What’s the use case there?
It seems you get all the benefit with almost no downside by just making them non-read/write but by going fully to non-enumerable you not introduce two massive downsides:
1. Introducing a whole new syntax that has multiple irregularities (property access) and uses a special character.
2. Now can confusingly have the same public and private names on the same class.
1. Introducing a whole new syntax that has multiple irregularities (property access) and uses a special character.
I sincerely fail to see how this has irregularities. It's straightforward. x.#prop is always a private field access and x.prop is always x["prop"] which is always an object property access. 2. Now can confusingly have the same public and private names on the same class.
I know what you're saying, but the reason it is confusing is because it is incorrect. You cannot have have any same public and private names because private names must start with # and public names cannot start with #. Private field names exist only in a class-definition-bound namespace.I know you can't think of a use case. But the committee of TC39 (language maintainers, popular library creators and maintainers) have thought of the use cases and have clearly decided it is useful.