What are getters and setters for?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
They let a property be backed by a function while still being read and written like an ordinary property.
const user = {
firstName: "Mai",
lastName: "Tran",
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
set fullName(value) {
[this.firstName, this.lastName] = value.split(" ");
},
};
user.fullName; // "Mai Tran" — no parentheses
user.fullName = "Nam Le"; // runs the setter
What they are good for
- Computed values that should look like data:
fullName,area,isExpired. - Validation on assignment, so an invalid value can never be stored.
- Keeping an API stable when a plain property later needs logic behind it — callers do not change.
- Lazy computation, calculating on first read and caching.
class Rectangle {
#width = 0;
get width() { return this.#width; }
set width(v) {
if (v < 0) throw new RangeError("width must be positive");
this.#width = v;
}
}
Pair them with a private #field rather than the old _name convention, which is only a hint.
Things to watch
A getter must not be expensive or have side effects. Readers expect obj.x to be cheap, and a getter that fetches data or mutates state surprises everyone — including the debugger, which evaluates getters when you expand an object.
A getter without a setter makes the property silently read-only in sloppy mode; assignment throws in strict mode and modules.
And infinite recursion is easy to write: inside get name, referring to this.name calls the getter again. Back it with a differently named field.
When a method is better
If the operation is slow, takes arguments, or clearly does something, make it a method. user.getFullName() sets the right expectation; user.fullName should feel like reading a value.
