All topics
Objectsintermediate

Getters and Setters

Defining object properties backed by functions that run on access or assignment, letting you compute values or add validation transparently.

A getter or setter is a function that runs when a property is read or assigned, while looking like a plain property to the caller.

A getter/setter pair is like a smart thermostat display: you read a single number (the property) that's actually computed live from several sensors (a getter), and when you dial in a new target temperature (a setter), the internal system runs it through validation and translates it into the actual settings, all while you just interact with one simple dial.

Key Concepts

1
    class Temperature {
      #celsius = 0;
2
      get fahrenheit() { return this.#celsius * 9 / 5 + 32; }
      set fahrenheit(v) { this.#celsius = (v - 32) * 5 / 9; }
    }
3
    t.fahrenheit = 100;     // calls the setter
    t.fahrenheit;           // calls the getter
4
In an object literal.
    const user = {
      first: 'Asha', last: 'Rao',
      get full() { return `${this.first} ${this.last}`; }
    };
${this.first} ${this.last}
5
    user.full;      // 'Asha Rao' -- computed, always current
6
What they are actually for.Derived values that must not go stale. Storing fullName alongside first and last means keeping them in step. A getter cannot drift.
fullNamefirstlast
7
Validation on assignment.
8
    set age(v) {
      if (v < 0) throw new RangeError('age must be positive');
      this.#age = v;
    }
9
Changing an implementation without changing the interface. A plain property can become a getter later, and every caller keeps working — which is the compatibility argument.
10
The cautions.They must be cheap. obj.value looks free. A getter doing a database call or a heavy computation makes innocent-looking code slow, and nothing at the call site suggests it.
obj.value
11
They must not surprise. A getter with side effects — logging, mutating, incrementing — breaks the reader's assumption that reading a property is inert.
12
Serialisation includes them. JSON.stringify calls getters, which may be what you want or may execute something expensive unexpectedly.
JSON.stringify
13
An infinite loop is easy.
14
    set name(v) { this.name = v; }     // calls itself forever
15
Back them with a differently named private field.
16
Object.defineProperty is the lower-level form, and it is how you add one to an existing object, or make a property non-enumerable:
Object.defineProperty
17
    Object.defineProperty(o, 'id', { value: 1, writable: false,
                                     enumerable: false });
18
The rule of thumb. Use them for computed views of state and for validation. If the work is not trivial, make it a method — getReport() sets the right expectation where report does not.
getReport()report
19
What the interviewer is probing.1. "What is the risk of logic in a getter?" Probing: the hidden cost. Stalls: "None." *Moves up:* it looks like a property read, so an expensive computation runs on every access, including in loops and template rendering.
20
2. "How do you create a computed property?" Probing: the syntax. Stalls: "A method." *Moves up:* the get keyword, so it is accessed without parentheses — useful for a derived value like fullName.
21
3. "Why would a setter be useful?" Probing: the use case. Stalls: "Symmetry." Moves up: validation or normalisation on assignment, without changing how callers write to the property.
22
4. "What breaks if a getter has side effects?" Probing: the expectation. Stalls: "Nothing." Moves up: reading becomes non-idempotent, so a debugger inspecting the object changes program state.