So far, private fields are introduced as follows:
class MyClass {
#privateField = 123;
}
I’d like to propose a small extension: scoped private fields.
The following style is becoming popular in the JavaScript world. It benefits from scoped privacy:
private #data;
function createStringBuilder() {
return {
#data: '',
};
}
function add(sb, str) {
sb.#data += str;
}
function toString(sb) {
return sb.#data;
}
New in this code:
- The keyword
private
in the first line. - The ability to use private fields in object literals.
As a slight downside, you now always need to use the keyword private
:
class StringBuilder {
private #data = ''; // keyword is required
add(str) {
this.#data += str;
}
toString() {
return this.#data;
}
}
On the upside, this gives you the freedom to widen the scope of privacy:
private #data;
class StringBuilder {
#data = ''; // no keyword!
add(str) {
this.#data += str;
}
}
function toString(stringBuilder) {
return stringBuilder.#data;
}
Alternative syntax has been proposed:
- Keyword
private
not needed for “normal” private fields. - Two keywords if you want to widen the scope of privacy:
private
andouter
.
Example:
private #data;
class StringBuilder {
outer #data = ''; // keyword is now required
add(str) {
this.#data += str;
}
}
function toString(stringBuilder) {
return stringBuilder.#data;
}
FP example:
private #data;
function createStringBuilder() {
return {
outer #data: '', // keyword is now required
};
}
function add(sb, str) {
sb.#data += str;
}
function toString(sb) {
return sb.#data;
}
I'm dying to have a private modifier for class properties and methods, but I really don't care for JS going with this prefix of
#
I would much rather it be a keyword likeprivate
.I have never seen a language go with a prefix of
#
before. I do have a C#/Java/TypeScript background so I'm surely biased with the choice ofprivate
- it just reads easier, it's not implicit, and many other languages already use it. Coming to Javascript to explain "Oh by the way if you want a private method/property you'll need to prefix it with#
" I also understand why we cannot just start going with a prefix of:_
- because it currently works one way, so we cannot break that current functionality.I do wonder how this will affect TypeScript which is a superset of JS. I'm sure they'll just have tslint autofix
#
-->private
, but then they should behave the same so that nothing breaks.At this point I feel like I'm choosing TypeScript not for its typing but for its well featured classes. All I want for Christmas is to have these standard class features that many other languages have had for a long time; I just want TypeScripts classes to become part of the standard JS classes. I know the class keyword is still fairly new in JS, but it's like it was half implemented while people write code that breaks encapsulation and doesn't allow the language to provide these features that other languages commonly have.