← Back to JavaScript Course | Chapter 2: Functions & Objects | Lesson 8 of 10

JS Object Get/Set

Getter and setter methods let a property behave like a plain value from the outside, while actually running custom code whenever it is read or written -- computing a derived value on the fly, or validating and transforming a value before it is stored, all invisibly to whoever is using the property.

Defining a Getter

A getter, written as get propertyName() { ... } inside an object literal or class, runs its function body automatically whenever that property is read -- from the outside, it looks and behaves exactly like a plain property, with no parentheses needed to call it.

Note: Use a getter for any value that should always be freshly computed from other properties, rather than manually recalculating and storing it separately every time something changes.

Warning: A getter is accessed like a plain property (obj.propertyName), not called like a method (obj.propertyName()) -- adding parentheses would try to call whatever the getter returns.

Example: Defining a Getter

javascript
const circle = {
  radius: 5,
  get area() { return Math.PI * this.radius ** 2; },
};
console.log(circle.area); // no parentheses, looks like a property

Defining a Setter

A setter, written as set propertyName(value) { ... }, runs its function body automatically whenever that property is assigned -- letting you validate, transform, or redirect the assigned value before deciding how (or whether) to actually store it.

Note: Use a setter to enforce a validation rule or apply a transformation (like trimming whitespace) automatically on every assignment, rather than relying on every caller to remember to do it themselves.

Warning: A setter must be paired with some way to actually store the value (usually a differently-named backing property) -- a setter with no storage logic silently discards whatever is assigned.

Example: Defining a Setter

javascript
const user = {
  _age: 0,
  set age(value) {
    if (value < 0) throw new Error("Age cannot be negative");
    this._age = value;
  },
};
user.age = 25;
console.log(user._age);

Combining a Getter and Setter for the Same Property

Defining both a get and a set for the same property name lets it behave like a fully custom, validated, computed property -- readable and writable from the outside exactly like a plain property, while both directions run your own logic behind the scenes.

Note: Pair a getter and setter together whenever a property needs both custom read and custom write behavior, keeping the backing storage property clearly separated and consistently named.

Warning: Forgetting to define a setter for a property that also has a getter means any assignment attempt is silently ignored (or throws under strict mode), which can be confusing if not intentional.

Example: Combining a Getter and Setter for the Same Property

javascript
const temperature = {
  _celsius: 0,
  get fahrenheit() { return this._celsius * 9 / 5 + 32; },
  set fahrenheit(value) { this._celsius = (value - 32) * 5 / 9; },
};
temperature.fahrenheit = 100;
console.log(temperature._celsius);

Getters and Setters in Classes

Inside a class, get and set methods work exactly the same way as in an object literal -- defined once on the class, they automatically apply to every instance, letting each object of that class have consistent computed or validated property behavior without repeating the logic per instance.

Note: Define getters and setters as part of a class when every instance of that class should share the same computed or validated behavior for a property.

Warning: A class getter/setter pair that references this._propertyName still needs each instance's constructor to actually initialize that backing property, or reads may return undefined.

Example: Getters and Setters in Classes

javascript
class Circle {
  constructor(radius) { this.radius = radius; }
  get area() { return Math.PI * this.radius ** 2; }
}
console.log(new Circle(3).area);

When to Use Getters/Setters vs Plain Properties

A plain property is simpler and sufficient when no computation or validation is needed -- reach for a getter/setter specifically when a property needs to be derived from other data, or needs to enforce a rule on every assignment, keeping that logic in one place instead of scattered across every place the value is set.

Note: Start with plain properties by default, and convert to a getter/setter pair only once you actually need computed or validated behavior for that specific property.

Warning: Adding getters and setters for every property "just in case" adds unnecessary indirection and complexity for properties that never actually need custom behavior.

Example: When to Use Getters/Setters vs Plain Properties

javascript
const point = { x: 5 };
const circle = { radius: 5, get area() { return Math.PI * this.radius ** 2; } };
console.log(point.x, circle.area);
Common Mistakes
  1. Naming a getter and its backing storage property the same thing, causing infinite recursion when the getter tries to read the property it is itself defining.
  2. Defining only a getter (no setter) and then being confused when an attempted assignment to that property silently does nothing (or throws in strict mode).
  3. Overusing getters/setters for simple properties that do not need any computed or validated behavior, adding unnecessary complexity.
Chapter Summary
  • get propertyName() { } defines a getter, invoked automatically whenever the property is read.
  • set propertyName(value) { } defines a setter, invoked automatically whenever the property is assigned a new value.
  • A common pattern uses a differently-named backing property (like _name) to avoid the getter/setter recursing into itself.
Browser Support

Getter and setter syntax has been supported in every modern browser since ES5.

🔒

Chapter Quiz — Complete all 10 topics to unlock

0/10 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.