Getters and Setters in JavaScript

Getters and setters define property access behavior while preserving property-like syntax for callers. They are commonly used in classes and object prototypes to compute values, validate assignments, or maintain encapsulation.

A getter is a method-like function invoked when a property is read, while a setter runs when that property is assigned. The caller still uses normal property syntax such as `user.name` and `user.name = "Sam"`; there is no explicit method call.

In a class, getters and setters are declared with `get` and `set`. A getter normally returns a value, while a setter accepts exactly one value. A common pattern is to store the underlying state under a different property, such as `_name`, so the accessor does not recursively call itself.

Accessors are also part of JavaScript's property-descriptor system. With `Object.defineProperty()`, a property can have `get` and `set` functions instead of a normal data value. Accessor properties can therefore exist directly on objects or through prototypes, which connects them closely to JavaScript's prototype-based property lookup.

Getters are useful for derived values, such as `fullName`, because the value can be calculated when requested. Setters are useful when assignment needs validation or normalization, such as rejecting an invalid age or converting an input to a canonical representation.

Because getters execute code, reading a property is not necessarily a cheap or side-effect-free operation. Avoid surprising work or observable side effects in getters, and be careful with setters that trigger additional state changes or throw exceptions.

Key points

Interview questions

What is a getter and setter in JavaScript, and why would you use them?

A getter is invoked when a property is read, and a setter is invoked when a property is assigned. They let an API expose property-like syntax while executing custom logic. A getter can compute a derived value, while a setter can validate or normalize incoming data. They are useful when callers should not need to know how a value is stored or calculated.

Where does a getter defined in a JavaScript class live?

A getter declared in a class is normally installed as an accessor property on the class prototype, rather than as a separate getter function on every instance. When an instance property is read, JavaScript can find that accessor through the prototype chain. This allows instances to share the accessor behavior. The getter still runs with `this` referring to the object on which the property access was performed.

How can a getter or setter accidentally cause infinite recursion?

Recursion occurs when an accessor accesses or assigns the same property that it defines. For example, `get name() { return this.name; }` invokes the getter again instead of retrieving separate state. A common solution is to use a backing property such as `_name` or a private field such as `#name`. The accessor then exposes `name` while the backing field stores the actual value.

What is the difference between a data property and an accessor property descriptor?

A data property descriptor describes stored state through attributes such as `value`, `writable`, `enumerable`, and `configurable`. An accessor descriptor instead uses `get` and `set`, along with `enumerable` and `configurable`. A property descriptor cannot simultaneously use `value`/`writable` and `get`/`set`. This distinction matters when inspecting or defining properties with `Object.getOwnPropertyDescriptor()` and `Object.defineProperty()`.

What should you consider before putting significant work or side effects in a getter?

A getter looks like a simple property read, so callers may reasonably expect it to be inexpensive and free of surprising side effects. Expensive computation can become difficult to notice because every property access can trigger it. Side effects can also make debugging and framework rendering behavior harder to reason about. If work is substantial, explicit methods or deliberate memoization may communicate the cost more clearly.