← All concepts
Object-Oriented Programming

Getters and Setters

A getter runs code when a property is read, and a setter runs code when a property is assigned.

Loading visual…

Definition

A getter, defined with `get propName()`, and a setter, defined with `set propName(value)`, let a property look like a plain field from the outside while actually running a function underneath. Reading `obj.propName` invokes the getter and uses its return value, no parentheses needed, and writing `obj.propName = value` invokes the setter with `value` as its argument instead of just storing it directly. This makes two things possible that a plain property cannot do. A getter can compute a value on the fly from other data, like a `fullName` getter that joins `first` and `last`, so there is nothing to keep in sync. A setter can validate or transform an incoming value before it is stored, like rejecting a negative age, throwing, or clamping it, so invalid state never gets written to the backing field. By convention the real data is kept in a differently named property, often prefixed with an underscore like `_age`, since a setter named `age` that also tries to write directly to `this.age` would call itself again and overflow the call stack.

Examples

class Temperature {
  constructor(celsius) {
    this.celsius = celsius;
  }
  get fahrenheit() {
    return this.celsius * 9 / 5 + 32;
  }
}
new Temperature(20).fahrenheit; // 68, computed on read, no parentheses

fahrenheit is not stored anywhere, the getter recomputes it from celsius every time it is read.

class Account {
  #balance = 0;
  get balance() {
    return this.#balance;
  }
  set balance(value) {
    if (value < 0) throw new Error("Balance cannot be negative");
    this.#balance = value;
  }
}
const a = new Account();
a.balance = 100; // setter runs, passes validation
a.balance; // 100
a.balance = -5; // throws, #balance stays 100

Assigning to balance routes through the setter, which validates the incoming value before touching the private #balance field, so an invalid assignment never changes the stored value.

const obj = {
  _name: "Ada",
  get name() { return this._name; },
  set name(value) { this._name = value.trim(); },
};
obj.name = "  Grace ";
obj.name; // "Grace", whitespace trimmed by the setter

The setter transforms the incoming string before storing it, and the getter always reads back the already-cleaned value.

Where you see this

Practice this

Further reading