JS Object Get/Set
In this page:
const objectName = {
get propertyName() {
return value;
},
set propertyName(newValue) {
// assign
}
};
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.
Example: Defining a Getter
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.
Example: Defining a Setter
// Declare the constant `user`; its value is built below
// Declare the constant `user`; its value is built below
const user = {
_age: 0,
// Define the setter `age` taking `value`
// Define the setter `age` taking `value`
set age(value) {
if (value < 0) throw new Error("Age cannot be negative");
// Assign `value` to `this._age`
// Assign `value` to `this._age`
this._age = value;
},
};
// Assign `25` to `user.age`
// Assign `25` to `user.age`
user.age = 25;
// Print `user._age` to the console
// Print `user._age` to the console
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.
Example: Combining a Getter and Setter for the Same Property
// Declare the constant `temperature`; its value is built below
// Declare the constant `temperature`; its value is built below
const temperature = {
_celsius: 0,
get fahrenheit() { return this._celsius * 9 / 5 + 32; },
set fahrenheit(value) { this._celsius = (value - 32) * 5 / 9; },
};
// Assign `100` to `temperature.fahrenheit`
// Assign `100` to `temperature.fahrenheit`
temperature.fahrenheit = 100;
// Print `temperature._celsius` to the console
// Print `temperature._celsius` to the console
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.
Example: Getters and Setters in Classes
// Define the class `Circle`
// Define the class `Circle`
class Circle {
constructor(radius) { this.radius = radius; }
get area() { return Math.PI * this.radius ** 2; }
}
// Print `new Circle(3).area` to the console
// Print `new Circle(3).area` to the console
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.
Example: When to Use Getters/Setters vs Plain Properties
// Declare the constant `point`, set to `{ x: 5 }`
// Declare the constant `point`, set to `{ x: 5 }`
const point = { x: 5 };
// Declare the constant `circle`, set to `{ radius: 5, get area() { return Math.PI * this.radius ** 2; } }`
// Declare the constant `circle`, set to `{ radius: 5, get area() { return Math.PI * this.radius ** 2; } }`
const circle = { radius: 5, get area() { return Math.PI * this.radius ** 2; } };
// Print `point.x, circle.area` to the console
// Print `point.x, circle.area` to the console
console.log(point.x, circle.area);
- 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.
- 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).
- Overusing getters/setters for simple properties that do not need any computed or validated behavior, adding unnecessary complexity.
- 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.
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: