Private fields and static
In the lesson on getters, the property minutes showed the object's data by a rule. But the data itself, the property seconds, could be rewritten by any code outside the class. Sometimes that must not happen.
Picture a safe with a small window. The money is inside, and no hand can reach it. You can see the amount or put in a bill only through the window, and how the window works was decided by whoever built the safe.
In a class, the safe is a private field, and the window is the class's own methods and getters. Here is the class Money: it keeps an amount in cents and does not let outside code change it.
class Money {
#cents;
constructor(cents) {
this.#cents = cents;
}
get dollars() {
return this.#cents / 100;
}
static fromDollars(dollars) {
return new Money(dollars * 100);
}
}
const m = Money.fromDollars(3);
console.log(m.dollars, m.fromDollars); // 3 undefinedPrivate fields
A private field is a field whose name starts with #. It is declared in the class body, like #cents; above, and methods read and change it through this.#cents.
The hash is part of the name: #cents and cents are two different fields. A syntax error, after which the program does not start, comes up in two cases:
- the class uses
this.#cents, but the field#cents;is not declared in its body, even when the use is insideconstructor; - code outside the class writes
m.#cents: the field is not visible from outside.
This way a class protects its data: it can change only through the class's methods. This is where the safe comparison ends. A safe can be broken into, while code outside the class has no way to read a private field.
A getter without a setter
From the outside, the amount can be read only through the getter dollars. It cannot be changed: the class has no setter, and #cents is not visible from outside.
A property that has only a getter cannot get a value inside the class either: this.dollars = 5 in a method stops the program with a TypeError. That is why the data itself lives under another name, like #cents, and the getter only shows it.
Interviewers ask how to hide an object's data in JavaScript. The answer: with a private # field or with a closure.
Static methods
The class Money has one more special method, fromDollars. A static method is a method with the word static. It belongs to the class itself, like Array.isArray: it is called as Money.fromDollars(3), and the instance m lacks it.
Back to the furniture factory. An ordinary method is a skill of a finished chair. A static one is the factory's own order window: the factory takes the order and hands out a new chair.
Most often a static method does exactly that: it creates an object in another way than constructor does. The Money constructor expects cents, while fromDollars takes dollars and turns them into cents itself.
Let's walk through the last lines of the example:
Money.fromDollars(3)is called through the class and returnsnew Money(300).m.dollarsruns the getter and gives3:300 / 100.m.fromDollarsgivesundefined: the instance has no static method, and reading it raises no error.
Common mistake
A static method was called through an instance:
const price = m.fromDollars(5); // ✗TypeError: m.fromDollars is not a functionReading m.fromDollars gives undefined, and the parentheses try to call undefined as a function. A static method is called through the class: Money.fromDollars(5).
Key points
- A private
#field is declared in the class body and is not visible from outside. - A property with only a getter cannot be assigned, even inside the class.
- A static method is called through the class, and instances do not have it.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.